C# TCP服务器如何多次接收单个客户端发送的数据?
嘿,这个问题我之前做客户端服务端项目时也踩过坑!核心问题基本都是服务器端只写了单次接收逻辑,要么处理完一次就关了连接,要么没做循环监听。我分TCP和UDP两种最常见的场景给你说下解决方案:
TCP 场景(面向连接)
TCP是基于连接的协议,所以服务器要区分「等待新连接」和「处理已连接客户端的多次数据」这两个逻辑:
单客户端场景:循环监听已连接的socket
如果你的服务器只需要和一个客户端保持通信,那在接受连接后,用循环持续调用recv()即可,直到客户端主动断开:
# Python TCP服务器示例(单客户端) import socket # 初始化服务器socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 9999)) server_socket.listen(1) print("等待客户端连接...") # 接受客户端连接(这一步仅执行一次) client_conn, client_addr = server_socket.accept() print(f"已连接客户端: {client_addr}") # 循环接收客户端的多次数据 while True: # 接收数据,缓冲区大小设为1024字节 recv_data = client_conn.recv(1024) # 如果recv返回空字节串,说明客户端已断开连接 if not recv_data: print("客户端已断开,退出循环") break print(f"收到数据: {recv_data.decode('utf-8')}") # 关闭连接 client_conn.close() server_socket.close()
多客户端场景:用线程/进程处理每个连接
如果需要同时服务多个客户端,每次accept()到新连接后,就启动一个独立线程专门处理该客户端的循环接收逻辑,主线程继续等待新连接:
# Python TCP服务器示例(多客户端) import socket import threading # 处理单个客户端的函数 def handle_single_client(client_conn): while True: recv_data = client_conn.recv(1024) if not recv_data: print("客户端断开连接") break print(f"收到数据: {recv_data.decode('utf-8')}") client_conn.close() # 初始化服务器 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 9999)) server_socket.listen(5) # 最大等待连接数 print("多客户端TCP服务器启动,等待连接...") # 循环等待新客户端连接 while True: client_conn, client_addr = server_socket.accept() print(f"新客户端连接: {client_addr}") # 启动线程处理该客户端 client_thread = threading.Thread(target=handle_single_client, args=(client_conn,)) client_thread.start()
UDP 场景(无连接)
UDP是无连接协议,服务器不需要提前建立连接,直接循环调用recvfrom()就能持续接收来自客户端的多次数据:
# Python UDP服务器示例 import socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.bind(('localhost', 9999)) print("UDP服务器启动,等待数据...") while True: # recvfrom会返回数据和客户端地址 recv_data, client_addr = server_socket.recvfrom(1024) print(f"来自 {client_addr} 的数据: {recv_data.decode('utf-8')}")
常见坑点提醒
- 别处理完一次就关socket:很多新手写完一次
recv()就直接调用close(),导致后续数据无法接收。 - 注意缓冲区大小:如果客户端发送的消息超过
recv()的缓冲区大小,数据会被分段,这时候需要循环拼接数据(可以约定消息结束标记,比如换行符)。 - 加上异常处理:实际项目中要包裹
try-except块,处理网络中断、客户端异常断开等情况,避免服务器崩溃。
内容的提问来源于stack exchange,提问作者Computeshorts
相关产品推荐
相关产品推荐

