2009-06-23 108 views
5

我有一個簡單的Python腳本,它使用套接字模塊發送UDP數據包。該腳本在我的Windows機器上工作正常,但在我的Ubuntu Linux PC上,它發送的數據包稍有不同。在Windows中,IP標頭中的標誌字段爲零,但在Linux上使用相同的代碼創建了一個標誌字段設置爲4的數據包。我想修改腳本,使其在Windows和Linux上具有一致的行爲。設置IP標頭的標誌字段

是否有一種控制套接字模塊中的標誌字段的方法?或者,這是一個我必須在Linux中更改的設置?

+1

很高興看到上下文的腳本。 – Almad 2009-06-23 23:52:36

回答

2

我猜標誌字段實際上設置爲2 = b010而不是4 - 標誌等於4是一個無效的IP數據包。請記住,標記是IP Header中的3位值。我期望看到標誌值爲2的UDP數據報,意思是「不要分段」。

至於你的問題,我不認爲有一種方法可以直接設置IP標記,而不必去使用raw sockets。我不擔心它,因爲大多數應用程序沒有真正有理由直接使用IP甚至UDP/TCP標頭。

+0

是的,wireshark告訴我flags字段的值爲4,但仔細檢查後只設置了「Do not fragment bit」。我擔心我的數據包可能因爲沒有碎片標誌而掉線。 – user83753 2009-06-24 00:04:13

1

construct可能會完成這項工作嗎?

+0

很酷的模塊,我會看看那個。儘管如此,它並沒有解決我的標誌位問題。 – user83753 2009-06-24 00:06:40

6

這是我最終採取的路線。我在D.Shwley的回答的評論中關注了SashaN發佈的鏈接,並瞭解了爲什麼Linux的UDP數據包中設置了「不分片段」的原因。結果發現它與PMTU發現有關。長話短說,通過使用套接字對象中的setsockopts函數,您可以清除Python中的UDP數據包中的不碎片位。

import socket 
IP_MTU_DISCOVER = 10 
IP_PMTUDISC_DONT = 0 # Never send DF frames. 
IP_PMTUDISC_WANT = 1 # Use per route hints. 
IP_PMTUDISC_DO = 2 # Always DF. 
IP_PMTUDISC_PROBE = 3 # Ignore dst pmtu. 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.connect(("10.0.0.1", 8000)) 
s.send("Hello World!") # DF bit is set in this packet 
s.setsockopt(socket.SOL_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DONT) 
s.send("Hello World!") # DF bit is cleared in this packet