Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
简单Python UDP服务器:从本地主机以外的客户端接收数据包时出现问题_Python - Fatal编程技术网

简单Python UDP服务器:从本地主机以外的客户端接收数据包时出现问题

简单Python UDP服务器:从本地主机以外的客户端接收数据包时出现问题,python,Python,因此,我尝试使用的非常简单的代码如下: (也在这里): 发送: 接收: 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.recvfr

因此,我尝试使用的非常简单的代码如下:

(也在这里): 发送:

接收:

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程序没有接收数据包。我很困惑

非常感谢您的帮助。
提前感谢。

尝试绑定到接收端的所有本地接口:

sock.bind(("", UDP_PORT)) # could also use "0.0.0.0"
请注意,在接收UDP数据包时,操作系统的行为在绑定方面并不完全符合逻辑(也不一致),特别是对于多播流量。这是您得到的行为:

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的接口,这与Linux上的setsockopt(SO_BINDTODEVICE)非常相似。传入的UDP数据包不被该IP过滤,因此即使绑定到具体IP,也可以接收多播流量。(这可能是我第一次觉得Windows的行为比Linux的行为更加一致。)


Python不会将套接字的这些特定于操作系统的差异抽象出来(就像在其他领域一样)。只要您没有明确的理由不这样做,我建议始终绑定到0.0.0.0。

确保服务器端口在尝试执行
recvfrom
调用时处于打开状态。如果套接字读取失败的目标端口,则会出现此错误


我收到了相同的错误,并通过阅读此链接进行了修复-

因此,如果我想发送消息并接收响应,那么代码会是什么样子?像这样

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
最终解决了我的问题,它相当复杂,高度本地化

我也遇到过类似的问题。我知道你已经解决了这个问题,但是我想分享一下我是如何解决这个问题的

我发现的问题是我的防火墙设置。我发现这些数据包被Windows防火墙阻止

我也使用了Wireshark,它显示数据包正在被发送和接收。需要注意的是,Wireshark获取数据包的级别比Python应用程序低得多

通过在同一台PC上的一个端口上使用侦听器和另一个端口上的客户端在本地运行我的代码,防火墙不会阻止数据包。当我转向与外部机器接口时,防火墙规则开始起作用,阻止传入的数据包


更改防火墙策略修复了此问题。改变防火墙以实现这一目的有多种方法和固有的安全风险,因此我将把这一部分留给IT专业人士。:-)

谢谢你的回复。除了socket.INADDR\u ANY之外的每个选项都没有做任何操作,socket.INADDR\u ANY给出了一个错误,表示它找到了一个int,但需要一个字符串,所以我使用了:sock.bind((str(socket.INADDR\u ANY),UDP\u PORT)),但这产生了:socket.gairro:[Errno 11004]getaddrinfo在我实际尝试连接时失败。Argh,是的,socket.INADDR\u ANY只是映射到一个
int
,这对于Python
socket
模块是无用的。我将从答案中删除这一点。(当然,这并不能解决你的问题。)我最终解决了我的问题,它相当复杂,高度本地化,所以我将接受你的答案,因为我认为这对大多数有我所描述问题的人来说可能是一个很好的建议。
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