2

我正在尝试实现一个监听多个端口的非阻塞 python udp 服务器。

我在这个Stackover 帖子中找到了一些代码,并对其进行了修改以监听多个套接字,到目前为止,一切都很好。

我的代码如下。

#!/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

但它很糟糕,就像这样:

/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,做这样的事情的惯用方法是什么?

4

3 回答 3

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)
于 2012-06-10T12:48:27.913 回答
1

上面没有关于 Python 示例的 UDP。SOCK_STREAM 用于 TCP。

于 2013-08-01T11:13:54.517 回答
0

就像接受()一样。

对于UDP,你没有“连接”,所以没有accept()。

使用 sendto() 和 recvfrom() 和 SOCK_DATAGRAM。

除了应用程序可以应用和/或嵌入有效负载中的任何上下文之外,一个UDP数据报与来自同一主机的下一个数据报之间的协议没有任何关系。不保证来自同一主机和同一源/目标地址/端口元组的多个数据报与同一客户端应用程序相关。它是完全无连接的,因此任何状态都必须完全由应用程序和有效负载的内容来管理。

于 2015-06-21T21:35:28.063 回答