使用Python线程化udp数据

时间:2015-02-19 08:52:39

标签: python multithreading sockets udp

我试图实现UDP套接字的线程。

我希望能够等待客户端在线程中向我发送一些数据并等待另一个数据中的第一个数据。

import threading
import socket

class Broker():

    def __init__(self):
          self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
          self.sock.bind(('127.0.0.1', 4242))
          self.clients_list = []

    def talkToClient(self, ip):
            self.sock.sendto("ok", ip)

    def listen_clients(self):
            while True:
                msg, client = self.sock.recvfrom(1024)
                t = threading.Thread(None, self.talkToClient, None, (client,), None)

b = Broker()
b.listen_clients()

和我的客户

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

sock.sendto("connection", ('127.0.0.1', 4242))

while True:
    msg, b = sock.recvfrom(1024)
    print msg

问题是我的客户永远不会收到" ok"

1 个答案:

答案 0 :(得分:1)

您的主要问题是您没有启动您创建的主题。

t.start()

应该这样做。请确保您使用四个空格进行缩进。

我自己没有看到错误,但是一旦我添加了一些日志记录,就很明显了。代码最终看起来像这样:

import threading
import socket
import logging

class Broker():

    def __init__(self):
        logging.info('Initializing Broker')
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind(('127.0.0.1', 4242))
        self.clients_list = []

    def talkToClient(self, ip):
        logging.info("Sending 'ok' to %s", ip)
        self.sock.sendto("ok", ip)

    def listen_clients(self):
        while True:
            msg, client = self.sock.recvfrom(1024)
            logging.info('Received data from client %s: %s', client, msg)
            t = threading.Thread(target=self.talkToClient, args=(client,))
            t.start()

if __name__ == '__main__':
    # Make sure all log messages show up
    logging.getLogger().setLevel(logging.DEBUG)

    b = Broker()
    b.listen_clients()

我担心你会遇到其他问题,因为你的线程解决方案。默认情况下,大多数python模块都不是线程安全的,不幸的是这是true for the socket module as well。我很确定最终你的socket的内部状态会被破坏,因为你在一个线程中读取并在另一个线程中写入,或者可能在许多其他线程中,因为你为每个客户端生成了一个新进程。

如果你在Python中查看multi-threaded socket code examples,套接字通常只由一个线程拥有和使用。关键是不要为客户端重用监听套接字,而是在每个客户端连接后使用socket.accept为每个客户端创建一个新套接字。