如果socket仍然打开,Python侦听器会在读取所有数据后关闭

时间:2015-07-09 02:23:35

标签: python multithreading sockets

我正在使用以下代码在python中编写套接字侦听器:

    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    self.sock.bind((HOST,PORT))
    self.sock.listen(10)
    print('Listening...')

    try:
        while 1:
            conn, addr = self.sock.accept()
            print('Connection accepted from %s' % addr[0])

            curr_thread = GenericListenerThread(conn, addr)
            curr_thread.start()              

    except Exception as E:
        pass

接受连接,然后旋转一个新线程并将其从accept()和地址创建的套接字提供给它。

在GenericListenerThread类中,我有:

class GenericListenerThread(threading.Thread):

    def __init__(self, conn, addr):
        self.conn = conn
        self.addr = addr

        super().__init__()

    def run(self):
            self.read_socket()


    def read_socket(self):
        data = "data"
        socket_data = []
        try:
            while len(data) > 0:
    >>>>        data = self.conn.recv(4096)
                socket_data.append(data)
        except Exception as E:
            pass

        for i in range(0, len(socket_data)):
            socket_data[i] = socket_data[i].decode('utf-8')

        self.message = "".join(socket_data)

(实际上还有更多,但这实际上是相关的)

在客户端,我只有一个测试脚本:

import socket


mystr = 'aString'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',2358))

s.sendall(mystr.encode('utf-8'))
print('sent')
temp = b''
print('about to receive')
while True:
    data = s.recv(4096)
    if not data: break    
    temp = temp.decode('utf-8') + data.decode('utf-8')
    print(temp)

print('received')
temp = temp.decode('utf-8') + data.decode('utf-8')
print(temp)

调试时,我的“客户端”会“接收”。将断点放在侦听器代码中会使我进入用“>>>”表示的行。一旦它试图读取它两次(我假设它已经完成读取所有数据,所以如果它是> 4096字节则为3倍)代码就会下降。我已经尝试/排除了除了断点之外的所有地方,但没有任何反应。可能是线程正在死亡 - 我不知道该怎么说。

因此,实际在read_socket函数中执行的代码是:

data = "data"
socket_data = []
data = self.conn.recv(4096)
socket_data.append(data)
data = self.conn.recv(4096)

然后我的代码就会从地球上掉下来,因为我希望在上面的内容之后发生以下情况:

socket_data.append(data)
<checks while loop, sees we're done>
for in in range(0, len(socket_data):
   ......

但是,如果在客户端我在s.close()行之后添加s.sendall...它可以正常工作,但是当它尝试发送响应时,客户端已停止监听。

所以我想我的问题是:如何在保持线程活动的同时成功读取此套接字中的所有数据,以便我可以发送响应?

编辑:

澄清问题的是,一旦读取了所有数据,线程似乎就会消失,其余的代码都不会被执行。因此,for函数中的read_socket循环永远不会被执行,因此我甚至无法做出回发的响应。但是,如果在客户端上添加s.close(),则一切都按预期进行。

0 个答案:

没有答案