当前位置: 首页 > backend >正文

深入解析 Python 的 socket 库:从基础通信到网络编程实战

深入解析 Python 的 socket 库:从基础通信到网络编程实战

在网络应用开发中,“通信”是最基本的能力。而在 Python 中,实现通信的核心库就是 socket。本文将全面介绍 socket 库的原理、用法与实战技巧,带你从入门走向精通。


一、什么是 socket?

socket 是一种“套接字”机制,是网络通信的基础。它抽象了底层 TCP/IP 协议栈的复杂性,使得程序员可以通过统一的接口,实现本地与远程主机之间的数据传输。

🧠 简单理解:

  • Socket = IP + Port + 协议;
  • 客户端通过 socket 向服务器发起连接;
  • 服务端监听某个端口等待连接;
  • 成功连接后,双方可以像“打电话”一样进行收发数据。

二、socket 类型与协议

Python 的 socket 支持两种主要的传输协议:

协议类型描述socket 类型
TCP面向连接、可靠传输socket.SOCK_STREAM
UDP无连接、不可靠传输socket.SOCK_DGRAM

通常网络应用大多基于 TCP,实时/广播类则可能基于 UDP。


三、基本 API 结构

Python 的 socket 库提供了简洁而强大的接口:

import socket# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # TCP
# s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # UDP

参数解释:

  • AF_INET:IPv4;
  • SOCK_STREAM:TCP;
  • SOCK_DGRAM:UDP。

四、TCP 通信:客户端与服务端示例

✅ 服务端(TCP Server)

import socketserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 8080))
server.listen(1)  # 同时最多连接数print("等待客户端连接...")
conn, addr = server.accept()
print(f"客户端连接自:{addr}")data = conn.recv(1024).decode()
print("收到消息:", data)
conn.send("你好,客户端!".encode())conn.close()
server.close()

✅ 客户端(TCP Client)

import socketclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('localhost', 8080))client.send("你好,服务端!".encode())
data = client.recv(1024).decode()
print("收到服务端回复:", data)client.close()

💡 运行方式:

  1. 启动服务端脚本;
  2. 再运行客户端脚本。

五、UDP 通信示例

UDP 是无连接的,传输效率高但不保证可靠性。

服务端(UDP Server)

import socketserver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('localhost', 9999))
print("UDP 服务端启动,等待接收数据...")while True:data, addr = server.recvfrom(1024)print(f"来自 {addr} 的消息:{data.decode()}")server.sendto("收到消息,谢谢!".encode(), addr)

客户端(UDP Client)

import socketclient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto("你好 UDP 服务端!".encode(), ('localhost', 9999))data, addr = client.recvfrom(1024)
print("服务端回复:", data.decode())client.close()

六、常用方法速查

方法说明
socket()创建 socket
bind((host, port))绑定 IP 与端口(服务端用)
listen(n)监听连接(TCP)
accept()接收连接,返回连接与地址
connect((host, port))客户端连接到服务端
send() / sendall()发送数据(TCP)
recv(bufsize)接收数据(TCP)
sendto() / recvfrom()UDP 的发送与接收
close()关闭 socket
settimeout(seconds)设置超时时间

七、进阶用法:多线程处理客户端

单线程服务端一次只能处理一个客户端,我们可以引入 threading 实现并发连接处理。

import socket
import threadingdef handle_client(conn, addr):print(f"新连接:{addr}")data = conn.recv(1024).decode()print(f"来自{addr}的消息:{data}")conn.send("你好,客户端!".encode())conn.close()server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 8081))
server.listen(5)
print("多线程服务端启动...")while True:conn, addr = server.accept()t = threading.Thread(target=handle_client, args=(conn, addr))t.start()

八、调试技巧与常见问题

1. 地址重用错误

OSError: [Errno 98] Address already in use

解决:

server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

2. recv 阻塞问题

recv() 是阻塞式的,若希望非阻塞,可设置:

s.settimeout(5)  # 超时 5 秒

3. 编码问题

始终建议传输 bytes 类型,因此记得 .encode().decode() 配对使用。


九、实战案例:简易聊天室

我们来实现一个基于 TCP 的简易聊天室服务端:

# server_chat.py
import socket
import threadingclients = []def handle_client(conn, addr):print(f"{addr} 已连接")clients.append(conn)while True:try:msg = conn.recv(1024).decode()if not msg:breakprint(f"{addr} 说:{msg}")for c in clients:if c != conn:c.send(f"{addr} 说:{msg}".encode())except:breakclients.remove(conn)conn.close()server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 9000))
server.listen(5)
print("聊天室服务端启动...")while True:conn, addr = server.accept()threading.Thread(target=handle_client, args=(conn, addr)).start()

客户端连接聊天:

# client_chat.py
import socket
import threadingclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('localhost', 9000))def recv_msg():while True:try:data = client.recv(1024).decode()print(data)except:breakthreading.Thread(target=recv_msg, daemon=True).start()while True:msg = input()client.send(msg.encode())

🔚 总结

Python 的 socket 模块是构建一切网络通信程序的基础,它封装了底层的 BSD Socket 接口,使得开发跨平台的网络应用变得简单。

🧰 你可以用 socket 实现:

  • Web 服务(配合 HTTP 协议);
  • 聊天室、游戏后端;
  • 物联网设备通信;
  • 自定义的远程调用协议。

📌 小贴士

  • 使用 socketserver 模块可以简化部分服务端开发;
  • 网络编程建议加入异常处理和日志;
  • 若需更高性能或异步并发,可参考 asyncioselectors

http://www.xdnf.cn/news/14031.html

相关文章:

  • 无人机抛投器模块使用与技术分析!
  • 篇章六 系统性能优化——资源优化——CPU优化(3)
  • React第六十二节 Router中 createStaticRouter 的使用详解
  • pmset - 控制 macOS 系统电源、睡眠、唤醒与节能
  • c++的STL库里的fill
  • 自主 Shell 命令行解释器
  • Dify创建 echarts图表 (二)dify+python后端flask实现
  • [MSPM0开发]之七 MSPM0G3507 UART串口收发、printf重定向,解析自定义协议等
  • 如何解决答题小程序大小超过2M的问题
  • C#使用ExcelDataReader高效读取excel文件写入数据库
  • 华为云Flexus+DeepSeek征文|基于华为云一键部署 Dify 应用的性能测试实践:构建聊天应用并使用 JMeter做压力测试
  • HarmonyOS5 运动健康app(一):健康饮食(附代码)
  • 苹果获智能钱包专利,Find My生态版图或再扩张:钱包会“说话”还能防丢
  • 【论文阅读笔记】ICLR 2025 | 解析Ref-Gaussian如何实现高质量可交互反射渲染
  • pom文件引用外部jar依赖
  • Web开发实战:Gin + GORM 构建企业级 API 项目
  • 使用 C/C++ 和 OpenCV 判断是否抬头
  • Spring 事务传播行为详解
  • 自己的服务器被 DDOS跟CC攻击了怎么处理,如何抵御攻击?
  • 公司内网远程访问配置教程:本地服务器(和指定端口应用)实现外网连接使用
  • 29-Oracle 23ai Flashback Log Placement(闪回日志灵活配置)
  • 进程控制
  • Trae Builder 模式:从需求到全栈项目的端到端实践
  • 书写时垂直笔画比水平笔画表现更好的心理机制分析
  • Android binder内核漏洞研究(一)——环境搭建
  • 【MySQL基础】表的约束的类型与使用指南
  • 从Apache OFBiz 17.12.01的反序列化漏洞到Docker逃逸的渗透之红队思路
  • GaussDB 分布式数据库调优(架构到全链路优化)
  • C#实战:解决NPOI读取Excel单元格数值0.00001显示为1E-05的问题
  • [特殊字符] Harmony OS Next里的Web组件:网页加载的全流程掌控手册