1

我试图找到从 python 中的多个(大约 100 个)udp 数据报套接字读取的最简单方法。我看过龙卷风,但龙卷风吹捧的是 http/tcp 而不是 udp 支持。

现在我有专门用于每个 udp 套接字的线程;但是,这似乎不是很有效。

4

5 回答 5

3

SocketServer模块有一个内置的 UDP 服务器,带有线程和分叉选项。

另一种选择是使用select模块,它允许您只关注数据已经可供读取的套接字。

于 2012-07-02T06:17:21.643 回答
1

我必须承认我从未使用过它,但也许Twisted会满足您的需求。

它支持许多协议,甚至是串行连接。

于 2012-07-02T05:27:07.077 回答
1

我想对最初的问题添加一些评论,即使它已经有一个公认的答案。

如果您有多个需要独立处理的连接(或至少在没有太多同步的情况下进行处理),则可以为每个连接使用一个线程并进行阻塞读取。现代调度程序不会因为那个而杀死你。这是处理连接的一种相当有效的方法。如果您担心内存占用,您可以相应地减少线程的堆栈大小(不适用于 python)。

线程/进程将在大部分时间(等待新数据时)保持非忙等待状态,并且不消耗任何 CPU 时间。

如果您不想或不能使用线程,那么select调用肯定是要走的路。这也是低级和高效的等待,并且作为奖励,为您提供触发的套接字列表。

于 2012-07-02T06:54:36.990 回答
0

asyncoro支持异步 TCP 和 UDP 套接字(以及许多其他功能)。与其他框架不同,使用 asyncoro 进行编程与使用线程非常相似。一个简单的 UDP 客户端/服务器程序来说明:

import socket, asyncoro

def server_proc(n, sock, coro=None):
    for i in xrange(n):
        msg, addr = yield sock.recvfrom(1024)
        print('Received "%s" from %s:%s' % (msg, addr[0], addr[1]))
    sock.close()

def client_proc(host, port, coro=None):
    sock = asyncoro.AsynCoroSocket(socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
    msg = 'client socket: %s' % (sock.fileno())
    yield sock.sendto(msg, (host, port))
    sock.close()

if __name__ == '__main__':
    sock = asyncoro.AsynCoroSocket(socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
    sock.bind(('127.0.0.1', 0))
    host, port = sock.getsockname()

    n = 100
    server_coro = asyncoro.Coro(server_proc, n, sock)
    for i in range(n):
        asyncoro.Coro(client_proc, host, port)

asyncoro 尽可能使用有效的轮询机制。只有 Windows 和 UDP 套接字才使用低效的“选择”(但如果安装了pywin32 ,则对 TCP 使用高效的 Windows I/O 完成端口)。

于 2012-07-11T18:48:51.977 回答
0

我认为如果你坚持使用 tornado 的 ioloop 并想做 UDP 套接字处理,你应该使用 UDP 版本的 tornado IOStream。我在自己的项目中成功地做到了这一点。称它为 UDPStream 有点用词不当(因为它不是一个流),但基本的使用应该很容易集成到您的应用程序中。

参见代码: http: //kyle.graehl.org/coding/2012/12/07/tornado-udpstream.html

于 2012-12-07T20:36:04.743 回答