1. TCP回显服务器
任务目标
实现一个TCP回显服务器:客户端建立连接后发送任意文本消息,服务器接收该消息并原样返回给客户端。通过该案例掌握TCP socket编程中最基本的流程:创建socket、绑定地址、监听、接受连接、收发数据、关闭连接。
环境依赖
- Python 3.6+(标准库,无需额外安装第三方包)
- 操作系统:Windows / Linux / macOS 均可
核心代码
import socket
def run_server(host='127.0.0.1', port=8888):
# 1. 创建TCP socket
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 允许端口快速重用,便于调试重启
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 2. 绑定地址与端口
server_sock.bind((host, port))
# 3. 开始监听,backlog为等待队列长度
server_sock.listen(5)
print(f'[服务器] 已启动,监听 {host}:{port}')
try:
while True:
# 4. 接受客户端连接(阻塞等待)
client_sock, client_addr = server_sock.accept()
print(f'[服务器] 客户端 {client_addr} 已连接')
# 为每个客户端单独处理,避免一个客户端阻塞影响新连接
handle_client(client_sock, client_addr)
except KeyboardInterrupt:
print('\n[服务器] 手动停止')
finally:
server_sock.close()
def handle_client(client_sock, client_addr):
try:
while True:
# 5. 接收数据(最大1024字节)
data = client_sock.recv(1024)
if not data:
# 客户端关闭连接,recv返回空字节串
break
print(f'[服务器] 收到来自 {client_addr} 的消息: {data.decode()}')
# 6. 原样回显数据
client_sock.sendall(data)
print(f'[服务器] 已回显 {len(data)} 字节')
except ConnectionResetError:
print(f'[服务器] 客户端 {client_addr} 异常断开')
finally:
# 7. 关闭客户端连接
client_sock.close()
print(f'[服务器] 客户端 {client_addr} 连接已关闭')
def run_client(host='127.0.0.1', port=8888):
"""简易测试客户端:发送一行消息并打印回显结果"""
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_sock.connect((host, port))
msg = input('请输入要发送的消息: ')
client_sock.sendall(msg.encode())
echo_data = client_sock.recv(1024)
print(f'[客户端] 收到回显: {echo_data.decode()}')
client_sock.close()
if __name__ == '__main__':
import sys
if len(sys.argv) > 1 and sys.argv[1] == 'client':
run_client()
else:
run_server()
运行与验证
启动服务器(终端1):
python tcp_echo.py
启动客户端(终端2):
python tcp_echo.py client
验证步骤与通过条件:
- 服务器终端显示
[服务器] 已启动,监听 127.0.0.1:8888,说明socket创建、绑定、监听成功。 - 客户端输入任意文本(如
hello socket)后回车,客户端终端打印[客户端] 收到回显: hello socket,且内容与输入完全一致,说明回显功能正确。 - 服务器终端依次显示收到消息、回显字节数、连接关闭日志,说明收发与关闭流程完整。
- 在客户端按
Ctrl+C或直接关闭窗口,服务器应打印连接关闭信息且不崩溃,继续等待新连接。
核心流程说明
本案例完整覆盖TCP服务端的标准生命周期:socket() 创建 → bind() 绑定 → listen() 监听 → accept() 接受连接 → recv()/sendall() 收发数据 → close() 关闭。客户端则走 socket() → connect() → sendall() → recv() → close() 的对应流程。代码中 recv() 返回空字节串表示对端已关闭连接,这是TCP断开检测的标准方式。