Socket超时会杀死Python中的线程

问题描述 投票:0回答:1

我将在我的专用在线服务器中使用以下Python程序,我的疑问是,对于每个新的服务器连接,它都会创建新的线程号,并且我已经为子进程设置了超时函数,它工作正常,但线程号正在不断增加,我认为线程不太清楚。请给我彻底清除或终止线程进程的解决方案。

import socket
from threading import Thread

def on_new_client(client_socket, addr):
while True:
    client_socket.settimeout(10)
    data = client_socket.recv(1024).decode('utf-8')
    client_socket.settimeout(None)
    send="GOK"
    client_socket.send(send.encode())

    if not data:
        print('Disconnected')
        break
    print("Adr and data",addr,data)
client_socket.close()


def main():
host = '127.0.0.1'  # allow any incoming connections
port = 4001

s = socket.socket()
s.bind((host, port))  # bind the socket to the port and ip address
s.listen(5)  # wait for new connections

while True:
    c,addr=s.accept()  # Establish connection with client.
    print("New connection from:",addr)
    thread = Thread(target=on_new_client, args=(c, addr))  # create the thread
    thread.start()  # start the thread
c.close() #c.close()
thread.join()


if __name__ == '__main__':
main()
python multithreading sockets tcp timeout
1个回答
0
投票

您担心的是为每个新客户端连接创建的线程没有被正确清除,这导致线程数量不断增加。为了解决这个问题,有两个潜在的原因:

  1. 线程没有终止:如果客户端没有断开连接或 on_new_client 函数卡住,线程可能会保持活动状态。

  2. 线程没有被清理:线程结束后 工作,可能无法正确加入或清除。

您可以通过以下方式确保线程正确终止:

  • 更谨慎地使用线程模块。
  • 确保线程完成后连接。
  • 正确处理客户端套接字断开连接和超时。
  • 如果需要的话,为线程设置“daemon”属性 当主程序完成时终止。

代码的改进版本:

import socket
from threading import Thread

def on_new_client(client_socket, addr):
    try:
        while True:
            client_socket.settimeout(10)
            data = client_socket.recv(1024).decode('utf-8')
            client_socket.settimeout(None)
            
            if not data:
                print(f'Client {addr} disconnected')
                break
            
            send = "GOK"
            client_socket.send(send.encode())
            print(f"Address: {addr}, Data: {data}")
    
    except socket.timeout:
        print(f"Connection timed out for {addr}")
    
    except Exception as e:
        print(f"Error with client {addr}: {e}")
    
    finally:
        client_socket.close()
        print(f"Connection closed for {addr}")

def main():
    host = '127.0.0.1'
    port = 4001

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host, port))
    s.listen(5)
    
    print(f"Server started on {host}:{port}")
    
    while True:
        client_socket, addr = s.accept()
        print(f"New connection from: {addr}")
        
        thread = Thread(target=on_new_client, args=(client_socket, addr), daemon=True)  # Mark thread as daemon
        thread.start()  # Start the thread

if __name__ == '__main__':
    main()

下一步:

添加线程和连接状态的详细日志记录。 b.使用多个连接测试服务器以验证线程是否按预期清理。

© www.soinside.com 2019 - 2024. All rights reserved.