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

【Python】Python Socket 网络编程详解:从基础到实践​

Python Socket 网络编程详解:从基础到实践​


文章目录

  • Python Socket 网络编程详解:从基础到实践​
  • 前言
  • 一、Socket 基础认知​
    • 1.1 什么是 Socket​
    • 1.2 Socket 的工作流程​
    • 1.3 Socket 的类型​
  • 二、TCP Socket 编程​
    • 2.1 TCP 服务器实现​
    • 2.2 TCP 客户端实现​
    • 2.3 TCP 通信演示​
  • 三、UDP Socket 编程​
    • 3.1 UDP 服务器实现​
    • 3.2 UDP 客户端实现​
  • 四、Socket 编程高级应用​
    • 4.1 多线程处理多个客户端连接​
    • 4.2 带超时设置的 Socket​
  • 五、Socket 编程常见问题及解决方法​
    • 5.1 地址已被使用(Address already in use)​
    • 5.2 数据粘包问题​
  • 总结​


前言

在网络通信的世界里,Socket 就像一座桥梁,连接着不同的计算机,让数据能够在它们之间顺畅传递。Python 作为一门简洁而强大的编程语言,其内置的 socket 模块为网络编程提供了便捷的接口。本文将详细介绍 Python socket 网络编程的方方面面,通过多样的呈现方式和丰富的示例,帮助你深入理解并熟练运用这一技术。​


一、Socket 基础认知​

1.1 什么是 Socket​

Socket,通常被翻译为 “套接字”,是计算机网络中进行通信的端点。它就像一个插座,一端插在本地计算机上,另一端插在远程计算机上,通过这个 “插座”,两台计算机可以进行数据交换。在 Python 中,我们可以使用 socket 模块来创建和操作 Socket。​

1.2 Socket 的工作流程​

无论是客户端还是服务器,使用 Socket 进行通信都遵循一定的工作流程:​

  • 服务器端:创建 Socket -> 绑定 IP 地址和端口 -> 监听连接 -> 接受连接 -> 收发数据 -> 关闭连接​
  • 客户端:创建 Socket -> 连接服务器 -> 收发数据 -> 关闭连接​

1.3 Socket 的类型​

Python 中常用的 Socket 类型有两种:​

  • SOCK_STREAM:面向连接的 Socket,基于 TCP 协议。它提供可靠的、有序的、双向的字节流传输服务,在通信前需要建立连接,通信结束后需要关闭连接。​
  • SOCK_DGRAM:无连接的 Socket,基于 UDP 协议。它不保证数据的可靠传输和有序到达,但传输速度较快,适用于对实时性要求较高的场景。​

二、TCP Socket 编程​

TCP(传输控制协议)是一种面向连接的、可靠的传输层协议。下面通过具体示例来介绍 TCP Socket 编程的实现。​

2.1 TCP 服务器实现​

步骤解析:​

  • 创建 TCP Socket 对象,指定地址族为 AF_INET(IPv4),类型为 SOCK_STREAM。​
  • 使用 bind () 方法绑定服务器的 IP 地址和端口号,IP 地址可以是本地地址(localhost或 127.0.0.1),端口号选择 1024-65535 之间的未被占用端口。​
  • 使用 listen () 方法开始监听客户端的连接请求,参数指定最大等待连接数。​
  • 进入循环,使用 accept () 方法接受客户端的连接,该方法会返回一个新的 - Socket 对象(用于与该客户端通信)和客户端的地址。​
  • 通过新的 Socket 对象与客户端进行数据收发,使用 recv () 方法接收数据,send () 或 sendall () 方法发送数据。​
    通信结束后,关闭与客户端通信的 Socket 和服务器 Socket。​

示例代码:​

import socket# 创建TCP Socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 绑定IP和端口
server_address = ('localhost', 8888)
print(f'服务器绑定到 {server_address[0]}:{server_address[1]}')
server_socket.bind(server_address)# 监听连接,最大等待5个连接
server_socket.listen(5)try:while True:print('等待客户端连接...')# 接受客户端连接client_socket, client_address = server_socket.accept()try:print(f'接收到来自 {client_address} 的连接')# 接收客户端数据data = client_socket.recv(1024)print(f'收到数据: {data.decode("utf-8")}')# 发送响应数据response = '已收到你的消息,谢谢!'client_socket.sendall(response.encode('utf-8'))finally:# 关闭客户端连接client_socket.close()print(f'与 {client_address} 的连接已关闭')
finally:# 关闭服务器Socketserver_socket.close()print('服务器已关闭')

2.2 TCP 客户端实现​

步骤解析:​

  • 创建 TCP Socket 对象,同样指定地址族和类型。​
  • 使用 connect () 方法连接服务器,参数为服务器的 IP 地址和端口号。​
  • 与服务器进行数据收发。​
  • 通信结束后,关闭 Socket。​

示例代码:​

import socket# 创建TCP Socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 连接服务器
server_address = ('localhost', 8888)
print(f'连接到服务器 {server_address[0]}:{server_address[1]}')
client_socket.connect(server_address)try:# 发送数据message = 'Hello, Server! 我是客户端'print(f'发送数据: {message}')client_socket.sendall(message.encode('utf-8'))# 接收服务器响应data = client_socket.recv(1024)print(f'收到服务器响应: {data.decode("utf-8")}')
finally:# 关闭Socketclient_socket.close()print('客户端已关闭连接')

2.3 TCP 通信演示​

  • 先运行 TCP 服务器代码,服务器会开始监听连接。​
  • 再运行 TCP 客户端代码,客户端会连接到服务器并发送消息。​
  • 服务器收到消息后会发送响应,客户端收到响应后关闭连接,服务器也会关闭与该客户端的连接并继续等待新的连接。​

三、UDP Socket 编程​

UDP(用户数据报协议)是一种无连接的、不可靠的传输层协议。它不需要像 TCP 那样建立连接,直接发送数据报,适合对实时性要求高但对可靠性要求不高的场景,如视频直播、语音通话等。​

3.1 UDP 服务器实现​

步骤解析:​

  • 创建 UDP Socket 对象,指定地址族为 AF_INET,类型为 SOCK_DGRAM。​
  • 使用 bind () 方法绑定服务器的 IP 地址和端口号。​
  • 进入循环,使用 recvfrom () 方法接收客户端发送的数据报,该方法会返回数据和客户端的地址。​
  • 使用 sendto () 方法向客户端发送响应数据报,需要指定客户端的地址。​
  • 通信结束后,关闭服务器 Socket。​

示例代码:​

import socket# 创建UDP Socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 绑定IP和端口
server_address = ('localhost', 9999)
print(f'服务器绑定到 {server_address[0]}:{server_address[1]}')
server_socket.bind(server_address)try:while True:print('等待客户端数据...')# 接收客户端数据和地址data, client_address = server_socket.recvfrom(1024)print(f'收到来自 {client_address} 的数据: {data.decode("utf-8")}')# 发送响应数据response = '已收到你的数据'server_socket.sendto(response.encode('utf-8'), client_address)print(f'已向 {client_address} 发送响应')
finally:# 关闭服务器Socketserver_socket.close()print('服务器已关闭')

3.2 UDP 客户端实现​

步骤解析:​

  • 创建 UDP Socket 对象。​
  • 直接使用 sendto () 方法向服务器发送数据报,需要指定服务器的地址。​
  • 使用 recvfrom () 方法接收服务器的响应数据报。​
  • 通信结束后,关闭 Socket。​

示例代码:​

import socket# 创建UDP Socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)server_address = ('localhost', 9999)
message = 'Hello, UDP Server!'try:# 发送数据print(f'发送数据: {message}{server_address}')sent = client_socket.sendto(message.encode('utf-8'), server_address)# 接收响应print('等待响应...')data, server = client_socket.recvfrom(1024)print(f'收到来自 {server} 的响应: {data.decode("utf-8")}')
finally:print('客户端关闭')client_socket.close()

四、Socket 编程高级应用​

4.1 多线程处理多个客户端连接​

在 TCP 服务器中,默认情况下一次只能处理一个客户端连接。为了能同时处理多个客户端,可以使用多线程技术。​

示例代码:​

import socket
import threadingdef handle_client(client_socket, client_address):try:print(f'新线程处理来自 {client_address} 的连接')data = client_socket.recv(1024)print(f'收到 {client_address} 的数据: {data.decode("utf-8")}')response = '已收到消息,正在处理...'client_socket.sendall(response.encode('utf-8'))finally:client_socket.close()print(f'与 {client_address} 的连接已关闭')# 创建TCP Socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 8888)
server_socket.bind(server_address)
server_socket.listen(5)print(f'多线程服务器启动,监听 {server_address}')try:while True:client_socket, client_address = server_socket.accept()# 创建线程处理客户端client_thread = threading.Thread(target=handle_client,args=(client_socket, client_address))client_thread.start()
finally:server_socket.close()

4.2 带超时设置的 Socket​

在网络通信中,有时需要设置超时时间,避免程序一直阻塞在等待数据的状态。可以使用 settimeout () 方法为 Socket 设置超时时间。​

示例代码(客户端):​

import socketclient_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.settimeout(5)  # 设置超时时间为5秒server_address = ('localhost', 8888)try:client_socket.connect(server_address)client_socket.sendall('Hello, Server!'.encode('utf-8'))data = client_socket.recv(1024)print(f'收到数据: {data.decode("utf-8")}')
except socket.timeout:print('连接或接收数据超时')
finally:client_socket.close()

五、Socket 编程常见问题及解决方法​

5.1 地址已被使用(Address already in use)​

当关闭服务器后立即重新启动,可能会遇到 “Address already in use” 的错误。这是因为关闭 Socket 后,端口不会立即释放,处于 TIME_WAIT 状态。可以通过设置 SO_REUSEADDR 选项来解决。​

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)​
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 允许端口重用​

5.2 数据粘包问题​

在 TCP 通信中,由于 TCP 是流式传输,可能会出现数据粘包的问题,即多个数据包被合并成一个接收。解决方法可以是在数据前加上数据长度,或者使用分隔符等。​

示例(使用分隔符):​

# 发送方
message = 'Hello|World|Python'
client_socket.sendall(message.encode('utf-8'))# 接收方
data = client_socket.recv(1024).decode('utf-8')
messages = data.split('|')
for msg in messages:print(msg)

总结​

Python socket 网络编程是实现网络通信的基础,通过本文的介绍,我们了解了 Socket 的基本概念、TCP 和 UDP 两种通信方式的实现,以及一些高级应用和常见问题的解决方法。​

在实际开发中,还需要考虑网络异常处理、数据加密、并发控制等问题。希望本文能为你打开 Python socket 网络编程的大门,通过不断实践和探索,掌握更多网络编程技巧。​

http://www.lryc.cn/news/624691.html

相关文章:

  • 云原生俱乐部-mysql知识点归纳(1)
  • 【前端面试题】JavaScript 核心知识点解析(第十四题解析到第二十二题)
  • 【牛客刷题】正六边形阴影面积计算
  • FastRTSP介绍
  • 微电网管控系统中python多线程缓存与SQLite多数据库文件连接池实践总结(含源码)
  • 多台服务器批量发布arcgisserver服务并缓存切片
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频内容理解与智能预警升级(401)
  • Python入门Day18:模块与包(module package)
  • Spring Boot + Spring Kafka 集成
  • SMTPman,smtp ssl助力安全高效邮件传输!
  • Java 中表示数据集的常用集合类
  • 低端设备加载webp ANR
  • 安全存储之 SAES+HUK 使用技巧和常见问题 LAT1543
  • Rust 教程之简介000
  • CSS:水平垂直居中
  • 【银河麒麟桌面系统】配置匿名文件夹与用户认证共享服务
  • 2025年秋招Java后端面试场景题+八股文题目
  • AI 推荐系统云端部署实战:基于亚马逊云科技免费资源的工程实现
  • 从财务整合到患者管理:德国医疗集团 Asklepios完成 SAP S/4HANA 全链条升级路径
  • CAN总线的安全性
  • Linux小白加油站,第三周周考
  • 世界模型之自动驾驶
  • 想找出版社出书?这样选就对了!
  • 《P1195 口袋的天空》
  • OVS:ovn是如何支持组播的?
  • GPT-5之后:当大模型更新不再是唯一焦点
  • 多硬盘构建lvm存储
  • GPT-5博士级AI使用教程及国内平替方案
  • 基于SpringBoot+Uniapp的互联网订餐小程序(协同过滤算法、Echarts图形化分析)
  • “Let it Crash“:分布式系统设计的涅槃重生哲学