2016-03-04 35 views
0

我已经开始学习UDP套接字,但由于某些原因,此代码抛出错误。为什么这个代码:socket.recvfrom(1024)抛出socket.error提供的无效参数

s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
x=s.recvfrom(1024) 

抛出提供的无效参数错误?

+1

作品对我来说是客户端,您可以显示完整的错误输出和追溯? – cdarke

+0

你在windows上运行吗?既然你没有绑定一个端口,我不知道会发生什么......在我的linux机器上,我没有收到错误,但是这个调用也没有返回。在Windows上可能存在潜在的权限错误。 – tdelaney

+0

@tdelaney是啊即时通讯使用Windows。我将如何将它绑定到端口? –

回答

4

UDP数据报通信发生在源端口和目标端口之间。您可以通过拨打bind来为端口分配一个端口,或者让网络协议栈为您选择一个端口,只需调用send/recv方法即可。如果您拨打sendto(并且您没有绑定端口),堆栈将在动态端口范围内分配一个号码。如果您致电recvfrom,堆栈通常会分配端口0.但是没有端口0.接下来会发生什么与平台有关。 Windows会尝试将你绑定为混杂的监听器。但这是一个特权呼叫,你可能会得到一个无效的参数错误。但如果你是管理员,这可能会奏效 - 我不确定。

要开始对话,发送内容的第一个实体需要知道要使用的目标端口。这意味着接收第一个通信的实体需要绑定到另一方事先知道的端口号。这可能是一个众所周知的端口号,硬连接到您的代码的端口,配置文件中的某些端口,甚至是通过名称服务协议(例如LDAP)进行广告的端口。

一旦收到第一个数据报,接收实体现在有发送者地址和端口号,所以可以回话。

在你的例子中,你的实体可以在一个知名的端口上达成一致并开始对话。这里是一个数据报echoer侦听端口9999

import socket 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.bind(('', 9999)) 
while 1: 
    data, addr = s.recvfrom(8096) 
    s.sendto(data, addr) 

和连接它

import socket 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
for i in range(10): 
    s.sendto(str(i), ('', 9999)) 
    print(s.recvfrom(1024)) 
+0

深入了解Windows行为 - 从来不知道它。 – SergeyA