繁体   English   中英

在多线程中的python socket recv

[英]python socket recv in multithread

我有只有一个套接字对象连接到Java服务器的python脚本。

我启动了一个线程,用于每5秒向服务器发送一次心跳消息。

另一个用于从服务器接收消息的线程。

顺便说一句,所有数据发送/接收都是原始缓冲区格式。

# socket_client.py

def recv_handler():
    global client_socket
    while True:
        try:
            # read 4 bytes first 
            pack_len = client_socket.recv(4)
            pack_len = struct.unpack('!i', pack_len)[0]
            # read the rest
            recv_data = client_socket.recv(pack_len)
            # decode
            decompressed_data = data_util.decompressMessage(recv_data)
            sc_pb_message = data_util.decodePBMessage(decompressed_data)
            sc_head = data_util.parseHead(sc_pb_message)
        except:
            print 'error'

def heart_handler():
    global client_socket
    while True:
        if client_socket:
            message = data_util.makeMessage('MSG_HEART_BEAT')
            compressed_data = data_util.compressMessage(message)
            send_data = data_util.makeSendData(compressed_data)
            try: 
                client_socket.send(send_data)
            except: 
                print 'except'
                pass
        time.sleep(5)

def connect(address, port):
    global client_socket
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect((address, port))

    # thread sending heart beat message
    th = threading.Thread(target = heart_handler)
    th.start()

    # thread recving message
    tr = threading.Thread(target = recv_handler)
    tr.start()

上面的代码可以正常工作。 该脚本将每5秒发送一次心跳消息,并从服务器接收消息,并且消息可以成功解码。

这就是触发部分,这是我不知道如何实现的。

我的python脚本需要同时从浏览器接收输入,因此我启动了BaseHTTPServer来处理来自浏览器的POST请求。

当请求到来时,我想调用client_socket.send方法将特定消息发送到服务器,当然我需要将服务器中的数据返回给浏览器。

# http_server.py

def do_POST(self):
    # ...
    result = socket_client.request(message)
    self.send_response(200)
    self.end_headers()
    self.wfile.write(...)

这是我在请求中尝试执行的操作:

def request(message):
    global client_socket
    client_socket.send(message)
    pack_len = client_socket.recv(4)
    pack_len = struct.unpack('!i', pack_len)[0]
    recv_data = client_socket.recv(pack_len)
    return recv_data

我遇到的问题是,在调用send方法后,在请求方法中收到的数据似乎被线程中的心跳数据所打扰。

如果我注释掉心跳线程和接收线程,那么request方法就可以正常工作。 来自服务器的数据可以正确解码,并且可以成功发送回浏览器。

我的解决方案现在可能是错误的,我真的不知道如何进行这项工作。

任何建议将不胜感激,谢谢:)

Python中的socket对象不是线程安全的,您需要借助一些同步原语(例如Python中的threading.Lock )访问共享资源(在本例中为client_socket对象)。在此处查找类似的问题: Python :套接字和线程?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM