MST

星途 面试题库

面试题:Python中多线程TCP服务器的基础实现

请用Python代码实现一个简单的多线程TCP服务器,要求能够接收客户端连接,并且可以处理多个客户端的并发请求,简述每个部分代码的作用。
22.8万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
import socket
import threading


def handle_client(client_socket, client_address):
    try:
        print(f"与 {client_address} 建立连接")
        while True:
            data = client_socket.recv(1024)
            if not data:
                break
            print(f"收到来自 {client_address} 的数据: {data.decode('utf-8')}")
            client_socket.sendall(b"数据已收到")
    except Exception as e:
        print(f"处理客户端 {client_address} 时发生错误: {e}")
    finally:
        client_socket.close()


def main():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_address = ('localhost', 12345)
    server_socket.bind(server_address)
    server_socket.listen(5)
    print("服务器正在监听 {}:{}".format(*server_address))

    while True:
        client_socket, client_address = server_socket.accept()
        client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
        client_thread.start()


if __name__ == "__main__":
    main()
  • 导入模块

    import socket
    import threading
    

    socket 模块用于网络通信,threading 模块用于多线程处理。

  • 定义处理客户端连接的函数

    def handle_client(client_socket, client_address):
        try:
            print(f"与 {client_address} 建立连接")
            while True:
                data = client_socket.recv(1024)
                if not data:
                    break
                print(f"收到来自 {client_address} 的数据: {data.decode('utf-8')}")
                client_socket.sendall(b"数据已收到")
        except Exception as e:
            print(f"处理客户端 {client_address} 时发生错误: {e}")
        finally:
            client_socket.close()
    
    • handle_client 函数接受客户端套接字和客户端地址作为参数。
    • try 块中,打印连接信息,然后通过循环接收客户端数据,接收到数据后打印并回发确认信息。
    • except 块捕获处理客户端过程中的异常并打印错误信息。
    • finally 块确保无论是否发生异常,最终都关闭客户端套接字。
  • 定义主函数

    def main():
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server_address = ('localhost', 12345)
        server_socket.bind(server_address)
        server_socket.listen(5)
        print("服务器正在监听 {}:{}".format(*server_address))
    
        while True:
            client_socket, client_address = server_socket.accept()
            client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
            client_thread.start()
    
    • 创建一个基于IPv4(AF_INET)和TCP协议(SOCK_STREAM)的套接字对象 server_socket
    • 设置套接字选项 SO_REUSEADDR 为1,允许在程序重启时重用相同的地址和端口。
    • 绑定服务器地址(localhost 和端口 12345)。
    • 开始监听,最大允许5个未完成的连接。
    • 通过无限循环接受客户端连接,每当有新连接时,创建一个新线程来处理该客户端,线程目标函数为 handle_client,并传入客户端套接字和客户端地址作为参数。
  • 程序入口

    if __name__ == "__main__":
        main()
    

    确保当脚本直接运行时,调用 main 函数启动服务器。