纠正多处理以在Python中处理UDP

时间:2012-05-03 16:01:12

标签: python udp multiprocessing

我正在尝试实现一个简单的UDP客户端和服务器。服务器应该收到一条消息并返回一个转换过的消息。

我对服务器的主要技巧是在循环中监听UDP消息,然后为每个传入消息生成multiprocessing.Process并在每个Process实例中发送回复:

class InputProcessor(Process):
    ...

    def run(self):
        output = self.process_input()
        self.sock.sendto(output, self.addr) # send a reply

if __name__ == "__main__":
    print "serving at %s:%s" % (UDP_IP, UDP_PORT)

    sock = socket.socket(socket.AF_INET,    # Internet
                         socket.SOCK_DGRAM) # UDP
    sock.bind((UDP_IP,UDP_PORT))

    while True:
        data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
        print "received message: %s from %s:%s" % (data, addr[0], addr[1])
        p = InputProcessor(sock, data, addr)
        p.start()

在测试客户端,我做这样的事情:

def send_message(ip, port, data):
    sock = socket.socket(socket.AF_INET,    # Internet
                         socket.SOCK_DGRAM) # UDP
    print "sending: %s" % data
    sock.sendto(data, (ip, port))
    sock.close()


for i in xrange(SECONDS*REQUESTS_PER_SECOND):
    data = generate_data()
    p = multiprocessing.Process(target=send_message, args=(UDP_IP,
                                                           UDP_PORT,
                                                           data))
    p.start()
    time.sleep(1/REQUESTS_PER_SECOND)

我在上面的代码中遇到的问题是,当REQUESTS_PER_SECOND变得高于某个值(~50)时,似乎某些客户端进程会收到指向不同进程的响应,即进程#1收到进程的响应#2,反之亦然。

请尽可能批评我的代码,因为我是网络编程的新手,可能会错过一些明显的东西。也许它因为某些原因使用Twisted,hovewer甚至更值得和更好,我对理解内部结构非常感兴趣。感谢。

2 个答案:

答案 0 :(得分:2)

根据之前的回答,我认为主要原因是UDP端口存在针对客户端的竞争条件。我没有看到在客户端代码接收,但可能它与服务器部分中的类似。我认为具体发生的是,对于低于50个请求/秒的值,请求 - 响应往返完成并且客户端退出。当更多请求到达时,可能有多个进程阻塞来读取UDP套接字,然后它可能是不确定的,客户端进程接收传入消息。如果在实际设置中网络延迟会更大,则会更快地达到此限制。

答案 1 :(得分:1)

非常感谢你们!我似乎已经找到了为什么我的代码以前失败了。我在客户端中使用multiprocessing.Manager().dict()来检查服务器的结果是否正确。但是,我没有使用任何锁来将一组写操作包装到dict(),因此虽然服务器的输出是正确的但是会出现很多错误。

很快,在客户端,我正在检查服务器响应是否正确。