我正在尝试实现一个非阻塞的python udp服务器,它可以监听多个端口。
我在这个Stackover posting中找到了一些代码并将其修改为在多个套接字上进行修改,到目前为止一直都很好。
我的代码如下。
#!/usr/bin/python
import select
import socket
ports_list=[7777,7778]
def make_socket(number):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', number))
sock.listen(5)
return sock
read_list= map(lambda x: make_socket(x), ports_list)
print(read_list)
print "Listening on port %s" % ports_list
while True:
readable, writable, errored = select.select(read_list, [], [])
for s in readable:
if s in read_list:
client_socket, address = s.accept()
read_list.append(client_socket)
print "Connection from", address
else:
data = s.recv(1024)
if data:
s.send(data)
else:
s.close()
read_list.remove(s)
我通过在另一个控制台中运行netcat来测试它
$ netcat localhost 7778
dsa
但它是这样的borks:
/udp_non_blocking_listener.py
[<socket._socketobject object at 0xb72804fc>, <socket._socketobject object at 0xb7280534>]
Listening on port [7777, 7778]
Connection from ('127.0.0.1', 41237)
Traceback (most recent call last):
File "./udp_non_blocking_listener.py", line 27, in <module>
client_socket, address = s.accept()
File "/usr/lib/python2.7/socket.py", line 202, in accept
sock, addr = self._sock.accept()
socket.error: [Errno 22] Invalid argument
我刚刚开始使用python非阻塞API,做这样的事情的惯用方法是什么?
答案 0 :(得分:3)
您不接受已接受的套接字不匹配。
您的固定代码(带有notAccepted
套接字的简介列表):
#!/usr/bin/python
import select
import socket
ports_list=[7777,7778]
def make_socket(number):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', number))
sock.listen(5)
return sock
read_list= map(lambda x: make_socket(x), ports_list)
print(read_list)
print "Listening on port %s" % ports_list
notAccepted = read_list[:]
while True:
readable, writable, errored = select.select(read_list, [], [])
for s in readable:
if s in notAccepted:
client_socket, address = s.accept()
read_list.append(client_socket)
print "Connection from", address, client_socket
else:
data = s.recv(1024)
if data:
s.send(data)
else:
s.close()
read_list.remove(s)
答案 1 :(得分:1)
上面没有关于Python示例的UDP。 SOCK_STREAM用于TCP。
答案 2 :(得分:0)
原样是接受()。
对于UDP,您没有“连接”,因此没有accept()。
使用sendto()和recvfrom()以及SOCK_DATAGRAM。
除了应用程序可以应用和/或嵌入有效载荷的任何上下文之外,在一个UDP数据报与来自同一主机的下一个UDP数据报之间的协议中没有关系。无法保证来自同一主机和同一源/目录地址/端口元组的多个数据报与同一客户端应用程序相关。它完全没有连接,因此任何状态都必须完全由应用程序和有效负载的内容管理。