我正在构建一个简单的客户端-服务器多人游戏,我想要连接 UDP 套接字。但是,当我调用 listen()
方法时,它会产生 Operation not support
异常。
try:
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind((host, port))
server.listen(5)
except socket.error, (value, message):
print "E: " + message # E: Operation not supported
有没有办法连接数据报套接字?
最佳答案
UDP 协议(protocol)是无连接的,因此您实际上无法以与 TCP 客户端和服务器相同的方式在 2 个套接字之间创建连接;因此,您也无法在 UDP 套接字上执行listen
系统调用,因为它仅涉及 TCP 服务器套接字。相反,您可以使用 socket.recvfrom
从任何地址接收数据报:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((host, port))
data, addr = sock.recvfrom(65536) # this will fit the maximum datagram
您可以通过解构addr
来响应客户端(如果它们仍然有一个打开的套接字),它是套接字的
,主机、端口
元组。 AF_INETsocket.SOCK_DGRAM
。
client_host, client_port = addr
您可以使用 sendto
将数据发送回那里
sock.sendto(data, (client_host, client_port))
如果你想使用众所周知的端口,你将绑定(bind)
套接字;如果没有,系统将为您分配一个端口。
可以在许多套接字实现上使用数据报套接字进行connect
系统调用;这充当一种过滤器,丢弃来自不需要的来源的数据包,并设置 sock.send
的默认传出地址(仍然可以使用 sock.sendto
code> 在这样的套接字上到另一个地址,尽管响应可能会因为“连接”而被丢弃)。如果客户端同意彼此使用 2 个众所周知的端口,这在客户端或 2 个节点之间非常有用。
但是,如果您在服务器上进行connect
,则它无法在此套接字上处理任何其他请求。此外,listen
及其队列仅与 SOCK_STREAM
套接字相关。
因此,如果 1 个服务器有多个客户端,您可以让服务器监听套接字 12345
,当客户端联系服务器时,服务器可以从 server:12345
包含一条消息,其中包含客户端应与服务器一起使用的另一个端口号。
关于Python 连接数据报套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28649968/