2012-07-18 35 views
0

我試圖模仿Python中C程序的某些部分的行爲。他們都在讀取一個二進制文件,其中每條記錄都是長度 - >數據。 C程序會從文件中提取長度字節,不管是正還是負,ntohl()都會返回正確的長度。然而,在Python,即使長度記錄是相同的值,當它的負我發現了一個OverflowError:作爲與CPython和C之間的ntohl和htonl不同的行爲

length: 419495936

ntohl: 281

length: -2147418112

OverflowError: can't convert negative number to unsigned long

length: 419495936

ntohl: 281

length: -2147418112

ntohl: 384

我在做什麼錯在這裏?我如何讓Python產生與C相同的結果?

編輯的代碼

這裏的C代碼:

while (fread(&rec_len, sizeof(unsigned int), 1, fp1) != 0) { 
    printf("length: %d\n", rec_len); 
    rec_len = ntohl(rec_len); 
    printf("ntohl: %d\n", rec_len); 

而這裏的Python:

with open(file, "rb") as f: 
    pSize = struct.unpack('<i', f.read(4))[0] 
    print "length: " + str(pSize) 
    packetSize = socket.ntohl(pSize) 
    print "ntohl: " + str(packetSize) 
    while packetSize > 0: 
     packet = f.read(packetSize) 
     pSize = struct.unpack('<i', f.read(4))[0] 
     print "length: " + str(pSize) 
     packetSize = socket.ntohl(pSize) 
     print "ntohl: " + str(packetSize) 
+3

你應該可能會顯示一些代碼... – mgilson 2012-07-18 12:58:51

+1

這隻適用於C,因爲它不能保護你免於溢出。 Python整數不會溢出,並且將一個非常負數視爲與某個大正數相同是沒有意義的。 – geoffspear 2012-07-18 13:07:07

+0

你的Python版本是什麼?在這種情況下,Python可能會在不同版本中顯示不一致的行爲http://stackoverflow.com/questions/5995971/python-error-with-socket-ntohl – jfs 2012-07-18 13:19:08

回答

5

你需要傳遞一個正數htonl()。如果你不能改變你的閱讀價值,你可以使用下面的代碼:

>>> socket.htonl((-2147418112) & 0xffffffff) 
384L 

編輯:已經看了你的代碼,你可以struct.unpack改變使用'<I'它給你一個無符號數,甚至可以使用'>I''!I',這樣就不需要使用ntohl()。

+0

謝謝,這已經很完美了。 – Dave 2012-07-18 13:11:43

+0

提及''I'''',它省去了'ntohl()'。 – glglgl 2012-07-18 13:35:20

相關問題