MST

星途 面试题库

面试题:Python搭建软件客户端服务器架构之基础通信

在使用Python搭建软件客户端服务器架构时,若要实现简单的基于TCP协议的客户端与服务器通信,简述服务器端和客户端的主要代码逻辑,并且说明如何处理多客户端连接?
38.4万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

服务器端主要代码逻辑

  1. 导入必要模块:使用 socket 模块来进行网络编程,例如 import socket
  2. 创建套接字对象:使用 socket.socket(socket.AF_INET, socket.SOCK_STREAM) 创建基于TCP协议的套接字对象,AF_INET 表示使用IPv4地址,SOCK_STREAM 表示TCP协议。
  3. 绑定地址和端口:使用 bind() 方法将套接字绑定到指定的IP地址和端口,如 server_socket.bind(('127.0.0.1', 12345)),这里 127.0.0.1 是本地回环地址,12345 是自定义端口。
  4. 监听连接:通过 listen() 方法开始监听客户端连接,例如 server_socket.listen(5),参数 5 表示允许的最大连接数。
  5. 接受客户端连接:使用 accept() 方法进入阻塞状态,等待客户端连接。当有客户端连接时,返回一个新的套接字对象和客户端的地址,如 client_socket, client_address = server_socket.accept()
  6. 数据收发:使用新的套接字对象 client_socket 进行数据的接收和发送,如 data = client_socket.recv(1024) 接收数据,client_socket.sendall(b'Hello, client!') 发送数据。
  7. 关闭连接:通信完成后,使用 client_socket.close() 关闭与客户端的连接,最后可使用 server_socket.close() 关闭服务器套接字。

客户端主要代码逻辑

  1. 导入必要模块:同样导入 socket 模块,import socket
  2. 创建套接字对象socket.socket(socket.AF_INET, socket.SOCK_STREAM) 创建TCP套接字。
  3. 连接服务器:使用 connect() 方法连接到服务器,如 client_socket.connect(('127.0.0.1', 12345))
  4. 数据收发:连接成功后进行数据的发送和接收,例如 client_socket.sendall(b'Hello, server!') 发送数据,data = client_socket.recv(1024) 接收数据。
  5. 关闭连接:通信结束后,使用 client_socket.close() 关闭套接字。

处理多客户端连接的方法

  1. 多线程
    • 在服务器端接受客户端连接后,为每个客户端创建一个新的线程来处理通信。例如使用 threading 模块,在接受客户端连接后:
    import threading
    def handle_client(client_socket, client_address):
        try:
            while True:
                data = client_socket.recv(1024)
                if not data:
                    break
                # 处理数据
                client_socket.sendall(b'Processed')
        except Exception as e:
            print(f'Error handling client {client_address}: {e}')
        finally:
            client_socket.close()
    
    while True:
        client_socket, client_address = server_socket.accept()
        client_thread = threading.Thread(target = handle_client, args=(client_socket, client_address))
        client_thread.start()
    
  2. 多进程
    • 与多线程类似,使用 multiprocessing 模块为每个客户端创建一个新的进程。但进程开销相对较大,适用于计算密集型任务场景,示例如下:
    import multiprocessing
    def handle_client(client_socket, client_address):
        try:
            while True:
                data = client_socket.recv(1024)
                if not data:
                    break
                # 处理数据
                client_socket.sendall(b'Processed')
        except Exception as e:
            print(f'Error handling client {client_address}: {e}')
        finally:
            client_socket.close()
    
    while True:
        client_socket, client_address = server_socket.accept()
        client_process = multiprocessing.Process(target = handle_client, args=(client_socket, client_address))
        client_process.start()
    
  3. 异步I/O(asyncio)
    • 使用Python的 asyncio 库来实现异步处理多个客户端连接。这种方式适用于I/O密集型任务,能有效提高效率。示例代码如下:
    import asyncio
    async def handle_client(reader, writer):
        try:
            while True:
                data = await reader.read(1024)
                if not data:
                    break
                # 处理数据
                writer.write(b'Processed')
                await writer.drain()
        except Exception as e:
            print(f'Error handling client: {e}')
        finally:
            writer.close()
    
    async def main():
        server = await asyncio.start_server(handle_client, '127.0.0.1', 12345)
        async with server:
            await server.serve_forever()
    
    asyncio.run(main())