当前位置: 首页 > 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.dtcms.com/a/338377.html

相关文章:

  • Street Crafter 阅读笔记
  • IDEA创建项目
  • MYSQL中读提交的理解
  • MySQL新手教学
  • lesson41:MySQL数据库进阶实战:视图、函数与存储引擎全解析
  • springBoot启动报错问题汇总
  • OVS:ovn是如何支持组播的?
  • LwIP 核心流程总结
  • wishbone总线
  • thinkphp8:一、环境准备
  • c++26新功能—可观测检查点
  • torch.nn.Conv1d详解
  • C++最小生成树
  • 高等数学 8.5 曲面及其方程
  • Python打卡Day45 预训练模型
  • 【加密PMF】psk-pmk-ptk
  • 【168页PPT】IBM五粮液集团数字化转型项目实施方案建议书(附下载方式)
  • 块体不锈钢上的光栅耦合表面等离子体共振的复现
  • 九联科技UMA223-H低功耗蜂窝模组在物联网设备中的应用与价值分析
  • 信号上升时间Tr不为0的信号反射情况
  • 工具集成强化学习:AI数学推理能力的新跃迁
  • Milvus向量数据库安装步骤
  • DRG/DIP支付改革如何通过大数据分析优化病种分组和权重调整?
  • 知识蒸馏 - 各类概率分布
  • CPP异常
  • 公司无公网IP,如何将内网服务,给外面异地连接使用?远程办公可通过什么访问?
  • 内联汇编(Inline Assembly)是什么?
  • redis命令行学习
  • Linux重要目录结构及目录命令
  • Vue3 中的 provide 和 inject 详解:实现跨组件通信