news 2026/7/31 8:52:26

Python Socket 常用代码汇总|TCP/UDP 服务端、客户端基础模板

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python Socket 常用代码汇总|TCP/UDP 服务端、客户端基础模板

前言

很多初学网络编程的小伙伴,弄懂Socket、TCP、UDP理论之后,最头疼的问题:到底有哪些通用代码模板?
网上代码零散,版本不一,经常出现端口占用、连接断开、编码报错、Windows/Linux兼容性问题。
本文整理Python标准库socket最常用、工程上高频使用的基础代码,全部基于Python3原生socket,无需第三方库,复制即可运行。

前置知识点:
TCP:面向连接、可靠、流式传输
UDP:无连接、不可靠、数据包传输
所有示例默认使用 IPv4 (AF_INET)

一、通用基础知识点

导入模块

importsocket

核心参数说明:

  • socket.AF_INET:IPv4
  • socket.SOCK_STREAM:TCP
  • socket.SOCK_DGRAM:UDP
  • bind((ip, port)):绑定地址端口
  • listen():开启监听(仅TCP)
  • accept():阻塞等待客户端连接(仅TCP)
  • recv(buffer):接收数据
  • send()/sendall():发送数据

⚠️ 重点:网络传输只能发送bytes字节流,字符串必须encode();收到字节需要decode()


二、TCP 全套常用模板

1. TCP 服务端(基础版)

持续监听,接收客户端消息,回传数据

importsocketdeftcp_server():# 创建socket对象 TCPserver_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 解决服务端重启端口立即复用,避免 WinError 10048 端口占用server_sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)# 绑定地址 0.0.0.0 监听本机所有网卡addr=("0.0.0.0",8888)server_sock.bind(addr)# 开启监听,参数为等待连接队列大小server_sock.listen(5)print(f"TCP服务端启动成功,监听{addr}")whileTrue:# 阻塞等待客户端接入client_conn,client_addr=server_sock.accept()print(f"新客户端连接:{client_addr}")try:whileTrue:# 最多接收1024字节data=client_conn.recv(1024)ifnotdata:# 空数据 = 客户端主动断开连接breakmsg=data.decode("utf-8")print(f"收到[{client_addr}]消息:{msg}")# 回复客户端resp=f"服务端已收到:{msg}"client_conn.sendall(resp.encode("utf-8"))exceptExceptionase:print("连接异常",e)finally:client_conn.close()print(f"客户端{client_addr}已断开")if__name__=="__main__":tcp_server()

2. TCP 客户端(基础版)

主动连接TCP服务端,发送消息并接收返回

importsocketdeftcp_client():client_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)server_addr=("127.0.0.1",8888)# 连接服务端client_sock.connect(server_addr)print("成功连接服务端")send_msg="Hello Socket TCP"client_sock.sendall(send_msg.encode("utf-8"))# 接收响应recv_data=client_sock.recv(1024)print("服务端返回:",recv_data.decode("utf-8"))client_sock.close()if__name__=="__main__":tcp_client()

3. TCP 客户端设置超时(非常常用)

防止网络阻塞,recv、connect永久卡死

importsocketdeftcp_client_timeout():client_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)client_sock.settimeout(5)# 设置超时5秒try:client_sock.connect(("127.0.0.1",8888))client_sock.sendall(b"test timeout")data=client_sock.recv(1024)print(data.decode())exceptsocket.timeout:print("连接/接收超时!")exceptConnectionRefusedError:print("无法连接,服务端未启动")finally:client_sock.close()if__name__=="__main__":tcp_client_timeout()

TCP注意事项:

  1. TCP是流式协议,存在粘包问题,大批量传输需要自定义数据包长度协议;
  2. 优先使用sendall()send()不一定一次性发送完所有数据;
  3. recv返回空字节代表对方关闭连接。

三、UDP 全套常用模板

1. UDP 服务端

UDP无连接,不需要listen、accept

importsocketdefudp_server():udp_sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)udp_sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)udp_sock.bind(("0.0.0.0",9999))print("UDP服务端启动,端口9999")whileTrue:data,addr=udp_sock.recvfrom(1024)msg=data.decode("utf-8")print(f"来自{addr}:{msg}")# 回包reply=f"UDP收到消息:{msg}"udp_sock.sendto(reply.encode("utf-8"),addr)if__name__=="__main__":udp_server()

2. UDP 客户端

importsocketdefudp_client():udp_sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)server_addr=("127.0.0.1",9999)msg="Hello UDP Socket"udp_sock.sendto(msg.encode("utf-8"),server_addr)# 等待接收返回data,addr=udp_sock.recvfrom(1024)print("服务端响应:",data.decode("utf-8"))udp_sock.close()if__name__=="__main__":udp_client()

UDP重点提醒:

  1. 无连接,就算服务端没启动,sendto也不会报错;
  2. 不存在连接断开的概念,不会感知对方是否在线;
  3. 不存在粘包,数据包独立;
  4. 不保证送达、不保证顺序。

四、高频实用工具代码片段

1. 获取本机内网IP

写socket程序经常需要获取本机地址

defget_local_ip():try:s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 随便连接一个公网地址,不真实发包,用来获取本机网卡IPs.connect(("8.8.8.8",80))ip=s.getsockname()[0]s.close()returnipexceptException:return"127.0.0.1"print(get_local_ip())

2. 判断端口是否被占用

调试socket必备工具

importsocketdefis_port_used(host="127.0.0.1",port=8888):sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.settimeout(1)result=Falsetry:sock.connect((host,port))result=TrueexceptConnectionRefusedError:result=Falsefinally:sock.close()returnresultprint(is_port_used(port=8888))

3. 简单十六进制收发(二进制通信常用)

很多硬件通信、内网隧道都是传输二进制数据

# 字符串转字节发送raw_data=bytes.fromhex("01 02 03 0A FF")# sock.sendall(raw_data)# 收到字节打印十六进制# data = sock.recv(1024)# print(data.hex())

五、常见踩坑总结(开发必看)

  1. 端口占用 WinError 10048
    解决:添加setsockopt(SO_REUSEADDR,1)
  2. 客户端只能本地访问,外部设备连不上
    原因:服务端绑定127.0.0.1,改为0.0.0.0
  3. UnicodeDecodeError 编码错误
    解决方案:通信双方约定编码(utf-8),不要直接解码未知二进制
  4. recv卡死程序
    解决方案:设置settimeout()超时捕获异常
  5. TCP大量数据收发乱码/拼接在一起
    根源:TCP粘包,需要自定义封包协议(先发送数据包长度)

六、学习路线建议

  1. 先跑通本文TCP客户端+服务端,理解连接生命周期
  2. 再学习UDP,理解无连接通信差异
  3. 解决TCP粘包,实现自定义协议通信
  4. 进阶:多线程处理多客户端连接(上面示例单线程只能处理一个客户端)
  5. 高阶:asyncio异步socket、自研内网穿透、代理隧道

七、拓展方向

掌握以上基础模板后,可以基于这些代码开发:

  • 简易聊天室
  • 内网穿透客户端/服务端
  • 硬件设备TCP/UDP数据采集
  • 简单端口扫描器
  • 自定义TCP代理服务
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 8:51:38

MinIO IAM Policy配置全解析:从基础概念到高级权限管理实战

1. 项目概述:为什么IAM Policy是MinIO安全管理的核心 如果你用过MinIO,肯定知道它是个好东西,对象存储嘛,开箱即用,性能也不错。但当你真的想把MinIO用起来,尤其是想给团队里不同的人分配不同的访问权限时&…

作者头像 李华
网站建设 2026/7/31 8:50:30

STC单片机烧录全攻略:从原理到实战,解决常见问题

1. 项目概述:从“烧录”说起,为什么它如此重要? 如果你刚接触单片机,尤其是STC的51系列,可能会对“烧录”这个词感到既熟悉又陌生。简单来说,烧录就是把我们写好的程序代码,通过特定的工具和方法…

作者头像 李华
网站建设 2026/7/31 8:50:19

压敏电阻原理与应用:从防雷卫士到电路保护设计实战

1. 从一次电源板维修说起:为什么是它?上个月,我帮朋友修一块工业控制器的电源板。故障现象很典型:设备在雷雨天后就彻底“趴窝”了。拆开一看,交流输入端一个蓝色或黄色的扁圆形元件炸裂了,碎片溅得到处都是…

作者头像 李华
网站建设 2026/7/31 8:48:57

C++ OpenCV图像处理:LUT查找表原理与实战性能优化

1. 项目概述:为什么LUT是图像处理的“快捷键”? 在C和OpenCV的图像处理世界里,我们经常需要对图像的像素值进行各种复杂的数学变换,比如伽马校正、对比度拉伸、颜色分级,甚至是实现一些特定的风格化滤镜。如果你每次都…

作者头像 李华
网站建设 2026/7/31 8:44:51

Nginx反向代理HTTPS服务报错排查:The plain HTTP request was sent to HTTPS port

1. 问题现场:一个看似简单却令人困惑的报错最近在给一个内部服务配置Nginx反向代理,让它通过HTTPS对外提供服务时,遇到了一个经典的报错:The plain HTTP request was sent to HTTPS port。这个错误信息直译过来就是“一个明文的HT…

作者头像 李华
网站建设 2026/7/31 8:43:21

逻辑分析仪阈值电压硬核选购标准全解析|电平判决原理、多电压系统适配、阈值设置避坑实战指南

专栏开篇导读 绝大多数硬件工程师选购逻辑分析仪时,只会盯着通道数、采样率、存储深度三大参数,90% 以上开发者都会忽略阈值电压可调能力这个核心硬性指标;等到调试不同内核电压电路板(5V 老单片机、3.3V 主流 STM32、1.8V 低压 FPGA)时,才发现固定阈值逻辑分析仪频繁出…

作者头像 李华