2013-03-31 25 views
9

所以,我試圖用非常簡單的代碼是在這裏:http://wiki.python.org/moin/UdpCommunication簡單的Python UDP服務器:從故障除localhost其他客戶端接收數據包

(也在這裏): 發送:

import socket 
UDP_IP = "127.0.0.1" 
UDP_PORT = 5005 
MESSAGE = "Hello, World!" 

print "UDP target IP:", UDP_IP 
print "UDP target port:", UDP_PORT 
print "message:", MESSAGE 

sock = socket.socket(socket.AF_INET, # Internet 
       socket.SOCK_DGRAM) # UDP 
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT)) 

接收:當我運行我的計算機上的兩個應用程序

import socket 

UDP_IP = "127.0.0.1" 
UDP_PORT = 5005 

sock = socket.socket(socket.AF_INET, # Internet 
       socket.SOCK_DGRAM) # UDP 
sock.bind((UDP_IP, UDP_PORT)) 

while True: 
    data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes 
    print "received message:", data 

的代碼工作正常。我把發送代碼放在我的筆記本電腦上:

UDP_IP="IP address for my computer" 

其他一切都是一樣的。然而,沒有任何反應。我做錯了什麼?我使用wireshark並確定數據包正在發送和接收;但是,python程序沒有收到數據包。我很困惑。

任何幫助,非常感謝。 在此先感謝。在收到UDP報文時約束力的條款

sock.bind(("", UDP_PORT)) # could also use "0.0.0.0" 

注意操作系統的行爲是不完全合乎邏輯的(也不是一致的),尤其是對多播流量:

回答

13

儘量結合在接收端所有的本地接口。這是你得到的行爲:

Linux:綁定到特定的IP將過濾器傳入的UDP數據包,只有針對這個特定IP的數據包將通過過濾器。這意味着例如當綁定到IP 192.168.1.100時,接收到IP 192.168.1.100的接口的組播UDP數據包將不會,而是接收到。在Linux上,普通綁定不會綁定到接口。爲此使用setsockopt(SO_BINDTODEVICE)。綁定到0.0.0.0(或Python上的「」)將始終接收機器在所有接口上接收到的所有UDP數據包,而不考慮目標IP,因此這通常是Linux上最有用的選項。

Windows:綁定到特定的IP將綁定到屬於這個IP的接口,非常像setsockopt(SO_BINDTODEVICE)在Linux上。傳入的UDP數據包不會被此IP過濾,因此即使綁定到具體IP,也可以接收多播通信。 (這可能是第一次在Windows行爲似乎更加一致對我來說比Linux的行爲。)

Python做抽象這些操作系統的具體差異離開插槽(因爲它在其他領域一樣)。只要你沒有明確的理由不這樣做,我建議總是綁定到0.0.0.0。

+0

感謝您的回覆。除了socket.INADDR_ANY之外,每個選項都不做任何事情,並且socket.INADDR_ANY給出了一個錯誤,表示它找到了一個int,但期望一個字符串,所以我使用了:sock.bind((str(socket.INADDR_ANY),UDP_PORT)),但這產生了:socket.gaierror:[Errno 11004] getaddrinfo失敗,當我實際上嘗試連接。 –

+0

嗯,奇怪。我現在沒有想法了...... –

+0

啊,是的,socket.INADDR_ANY只是映射到一個'int',這對Python'socket'模塊來說是沒用的。我會從答案中刪除。 (當然這並不能解決你的問題。) –

-1

所以,如果我要發送消息和接收響應,然後會如何代碼看起來?喜歡這個?

import socket 
UDP_IP = "127.0.0.1" 
UDP_PORT = 5005 
MESSAGE = "Hello, World!" 

sock = socket.socket(socket.AF_INET, # Internet 
       socket.SOCK_DGRAM) # UDP 
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT)) 

sock.bind((UDP_IP, UDP_PORT)) 

while True: 
    data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes 
    print "received message:", data 
4

eventually figured out my issue and it was pretty complex and highly localized,

我有一個非常類似的問題發生在我身上。我意識到你已經解決了這個問題,但是我認爲分享我是如何爲我解決問題的。

我發現的問題是我的防火牆設置。我發現數據包被Windows防火牆阻止。

我也使用過Wireshark,它顯示數據包正在發送和接收。需要注意的是,Wireshark抓取的數據包比Python應用程序低得多。

通過在同一臺PC上的一個端口上監聽器和另一個端口上的客戶端在本地運行我的代碼,防火牆不阻止數據包。當我轉移到與外部機器接口時,防火牆規則開始阻止傳入的數據包。

更改防火牆策略解決了此問題。改變防火牆以實現這一目標有許多方法和固有的安全風險,所以我將把這部分留給IT專業人員。 :-)

相關問題