Python Socket 编程实战:从零实现 Server 与 Client 通信

Python Socket 编程实战:从零实现 Server 与 Client 通信
在现代网络编程中,Socket(套接字) 是最基础、最重要的通信机制之一。无论是构建聊天应用、远程控制工具,还是理解 HTTP 协议底层原理,掌握 Socket 编程都是必备技能。本文将带你用 Python 从零开始编写一个简单的 TCP Server 和 Client,并深入讲解关键细节,助你真正理解“连接”背后的逻辑。
🧠 什么是 Socket?
简单来说,Socket 是网络上两个程序之间进行双向通信的端点。你可以把它想象成电话的听筒——一端拨号(Client),另一端接听(Server),双方建立连接后即可交换信息。
Python 的 socket 模块封装了底层 BSD Socket API,让我们能用简洁的代码实现网络通信。
🔧 环境准备
- Python 3.6+
- 无需额外安装库(
socket是标准库)
🖥️ 编写 TCP Server
我们先从服务端开始。服务端的核心任务是:
- 创建 Socket
- 绑定地址和端口
- 监听连接
- 接受客户端连接并处理数据
# server.py
import socket
def start_server(host='127.0.0.1', port=65432):
# 创建 TCP socket (AF_INET: IPv4, SOCK_STREAM: TCP)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# 允许端口重用(避免 TIME_WAIT 问题)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen()
print(f"✅ Server listening on {host}:{port}")
while True:
conn, addr = s.accept() # 阻塞等待连接
with conn:
print(f"📞 Connected by {addr}")
while True:
data = conn.recv(1024) # 接收最多 1024 字节
if not data:
break
message = data.decode('utf-8')
print(f"📥 Received: {message}")
response = f"Echo: {message}"
conn.sendall(response.encode('utf-8'))
if __name__ == "__main__":
start_server()
💡 注意:
SO_REUSEADDR选项非常实用,它允许你在程序重启时立即复用同一端口,避免“Address already in use”错误。
📱 编写 TCP Client
客户端的任务更简单:
- 创建 Socket
- 连接到服务端
- 发送/接收数据
# client.py
import socket
def send_message(host='127.0.0.1', port=65432, message="Hello, Server!"):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((host, port))
s.sendall(message.encode('utf-8'))
data = s.recv(1024)
print(f"📤 Sent: {message}")
print(f"📥 Received: {data.decode('utf-8')}")
if __name__ == "__main__":
send_message()
▶️ 运行测试
打开两个终端:
终端 1(启动服务端):
python server.py
# 输出:✅ Server listening on 127.0.0.1:65432
终端 2(运行客户端):
python client.py
# 输出:
# 📤 Sent: Hello, Server!
# 📥 Received: Echo: Hello, Server!
此时服务端也会打印:
📞 Connected by ('127.0.0.1', 54321)
📥 Received: Hello, Server!
⚠️ 常见陷阱与最佳实践
| 问题 | 解决方案 |
|---|---|
| 连接被拒绝 | 确保服务端已启动,且端口未被防火墙阻止 |
| 中文乱码 | 始终指定编码(如 utf-8),避免默认系统编码差异 |
| recv 数据不完整 | TCP 是流协议,需自行处理粘包/分包(例如加长度头或分隔符) |
| 阻塞导致卡死 | 对于多客户端场景,使用 threading、asyncio 或 select 实现并发 |
🌟 进阶建议:生产环境中不要直接用裸 Socket 处理复杂协议。可考虑
asyncio+StreamReader/StreamWriter,或使用高层库如Twisted、aiohttp。
🔄 扩展思考:如何支持多个客户端?
上面的服务端一次只能处理一个连接。若要支持并发,可以这样改造:
import threading
def handle_client(conn, addr):
with conn:
print(f"📞 New connection from {addr}")
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
# 在 accept 后启动新线程
while True:
conn, addr = s.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
当然,线程并非唯一选择——对于高并发场景,异步 I/O(如 asyncio)会更高效。
✅ 总结
通过本文,你已经掌握了:
- 如何用 Python 创建 TCP Server 和 Client
- 理解了
bind、listen、accept、connect、send/recv的作用 - 避开了常见编码与连接陷阱
Socket 编程看似底层,却是理解网络世界的钥匙。动手改一改代码,比如让客户端循环输入消息,或者加入心跳机制,你会收获更多!
最后提醒:永远不要在公网暴露未经验证的 Socket 服务,安全第一!
Happy Coding! 🐍
更多推荐



所有评论(0)