在这里插入图片描述

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

我们先从服务端开始。服务端的核心任务是:

  1. 创建 Socket
  2. 绑定地址和端口
  3. 监听连接
  4. 接受客户端连接并处理数据
# 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

客户端的任务更简单:

  1. 创建 Socket
  2. 连接到服务端
  3. 发送/接收数据
# 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 是流协议,需自行处理粘包/分包(例如加长度头或分隔符)
阻塞导致卡死对于多客户端场景,使用 threadingasyncioselect 实现并发

🌟 进阶建议:生产环境中不要直接用裸 Socket 处理复杂协议。可考虑 asyncio + StreamReader/StreamWriter,或使用高层库如 Twistedaiohttp


🔄 扩展思考:如何支持多个客户端?

上面的服务端一次只能处理一个连接。若要支持并发,可以这样改造:

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
  • 理解了 bindlistenacceptconnectsend/recv 的作用
  • 避开了常见编码与连接陷阱

Socket 编程看似底层,却是理解网络世界的钥匙。动手改一改代码,比如让客户端循环输入消息,或者加入心跳机制,你会收获更多!

最后提醒:永远不要在公网暴露未经验证的 Socket 服务,安全第一!


Happy Coding! 🐍

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐