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

【python】python进阶——网络编程

目录

引言

一、 网络编程基础

1.1 什么是网络编程?

1.2 基本概念

二、 Socket编程

2.1 创建Socket

2.2 TCP Socket工作流程

2.3 UDP Socket工作流程

三、高级网络编程框架

3.1 socketserver模块

3.2 异步网络编程

四、简单的聊天应用实现

五、常见问题与解决方案

5.1 端口占用问题

5.2 处理连接中断

5.3 设置超时

附录:Python网络编程API参考

socket模块核心API

Socket对象方法

socketserver模块核心类

asyncio网络编程核心API

select模块核心API

常见常量参数


引言

        网络编程是现代软件开发中不可或缺的一部分,而Python以其简洁的语法和强大的库支持,成为了网络编程的理想选择。

一、 网络编程基础

1.1 什么是网络编程?

        网络编程是指编写能够在网络环境中运行的程序,这些程序可以跨越不同的设备进行通信和数据交换。

1.2 基本概念

  • IP地址:设备的网络标识

  • 端口:应用程序的通信端点(0-65535)

  • 协议:通信规则(TCP、UDP、HTTP等)

  • Socket:网络通信的基础接口

二、 Socket编程

Socket是网络编程的核心,提供了不同主机间进程通信的端点。

2.1 创建Socket

import socket
​
# 创建TCP socket
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
​
# 创建UDP socket
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

参数说明:

  • AF_INET:IPv4地址族

  • SOCK_STREAM:TCP协议

  • SOCK_DGRAM:UDP协议

2.2 TCP Socket工作流程

服务器端:

import socket
​
# 创建TCP socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
​
# 绑定地址和端口
server_socket.bind(('localhost', 8888))
​
# 开始监听
server_socket.listen(5)
print("服务器启动,等待连接...")
​
while True:# 接受客户端连接client_socket, addr = server_socket.accept()print(f"接收到来自 {addr} 的连接")# 接收数据data = client_socket.recv(1024)print(f"收到数据: {data.decode()}")# 发送响应client_socket.send("你好,客户端!".encode())# 关闭连接client_socket.close()

客户端:

import socket
​
# 创建TCP socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
​
# 连接服务器
client_socket.connect(('localhost', 8888))
​
# 发送数据
client_socket.send("你好,服务器!".encode())
​
# 接收响应
response = client_socket.recv(1024)
print(f"服务器响应: {response.decode()}")
​
# 关闭连接
client_socket.close()

2.3 UDP Socket工作流程

服务器端:

import socket
​
# 创建UDP socket
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
​
# 绑定地址和端口
udp_socket.bind(('localhost', 9999))
​
print("UDP服务器启动,等待数据...")
​
while True:# 接收数据data, addr = udp_socket.recvfrom(1024)print(f"收到来自 {addr} 的数据: {data.decode()}")# 发送响应udp_socket.sendto("收到消息!".encode(), addr)

客户端:

import socket
​
# 创建UDP socket
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
​
# 发送数据
udp_socket.sendto("你好,UDP服务器!".encode(), ('localhost', 9999))
​
# 接收响应
response, addr = udp_socket.recvfrom(1024)
print(f"服务器响应: {response.decode()}")
​
# 关闭socket
udp_socket.close()

三、高级网络编程框架

3.1 socketserver模块

Python提供了更高级的socketserver模块,简化了网络服务器的创建。

TCP服务器示例:

import socketserver
​
class MyTCPHandler(socketserver.BaseRequestHandler):def handle(self):# 处理请求self.data = self.request.recv(1024).strip()print(f"{self.client_address[0]} 发送: {self.data.decode()}")# 发送响应self.request.sendall(self.data.upper())
​
if __name__ == "__main__":HOST, PORT = "localhost", 9999# 创建TCP服务器with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:print(f"服务器启动在 {HOST}:{PORT}")server.serve_forever()

3.2 异步网络编程

对于高性能网络应用,Python提供了asyncio模块。

异步TCP服务器示例:

import asyncio
​
async def handle_client(reader, writer):data = await reader.read(100)message = data.decode()addr = writer.get_extra_info('peername')print(f"收到来自 {addr} 的消息: {message}")writer.write(f"已接收: {message}".encode())await writer.drain()writer.close()
​
async def main():server = await asyncio.start_server(handle_client, '127.0.0.1', 8888)addr = server.sockets[0].getsockname()print(f'服务器运行在 {addr}')async with server:await server.serve_forever()
​
asyncio.run(main())

四、简单的聊天应用实现

一个简单的多客户端聊天服务器示例:

import socket
import threading
​
class ChatServer:def __init__(self, host='localhost', port=8888):self.host = hostself.port = portself.clients = []self.nicknames = []self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)def broadcast(self, message):for client in self.clients:try:client.send(message)except:self.remove_client(client)def remove_client(self, client):if client in self.clients:index = self.clients.index(client)self.clients.remove(client)nickname = self.nicknames[index]self.nicknames.remove(nickname)self.broadcast(f"{nickname} 离开了聊天室!".encode())def handle_client(self, client):while True:try:message = client.recv(1024)self.broadcast(message)except:self.remove_client(client)breakdef receive(self):self.server_socket.bind((self.host, self.port))self.server_socket.listen()print(f"服务器运行在 {self.host}:{self.port}")while True:client, address = self.server_socket.accept()print(f"连接到: {str(address)}")client.send("NICK".encode())nickname = client.recv(1024).decode()self.nicknames.append(nickname)self.clients.append(client)print(f"用户昵称: {nickname}")self.broadcast(f"{nickname} 加入了聊天室!".encode())client.send("连接到服务器!".encode())thread = threading.Thread(target=self.handle_client, args=(client,))thread.start()
​
if __name__ == "__main__":server = ChatServer()server.receive()

五、常见问题与解决方案

5.1 端口占用问题

# 设置SO_REUSEADDR选项解决端口占用
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

5.2 处理连接中断

try:data = client_socket.recv(1024)if not data:print("连接已关闭")break
except ConnectionResetError:print("客户端连接中断")

5.3 设置超时

# 设置接收超时
client_socket.settimeout(30.0)  # 30秒超时

附录:Python网络编程API参考

下面表格提供了Python网络编程中最常用API的完整参考,包括参数和返回值信息,可以帮助开发者更高效地使用Python进行网络编程。

socket模块核心API

API描述参数返回值示例
s.socket(family, type, proto)创建新的socket对象

family: 地址族(AF_INET/AF_INET6)

type: socket类型(SOCK_STREAM/

SOCK_DGRAM)

proto: 协议号(通常为0)

socket对象

s = socket.socket

(socket.AF_INET, socket.SOCK_STREAM)

s.gethostname()获取当前主机名字符串形式的主机名host = socket.gethostname()
s.gethostbyname(hostname)通过主机名获取IP地址hostname: 主机名字符串IP地址字符串ip = socket.gethostbyname('www.example.com')
s.gethostbyaddr(ip_address)通过IP地址获取主机信息ip_address: IP地址字符串(hostname, aliaslist, ipaddrlist)元组info = socket.gethostbyaddr('8.8.8.8')
s.getservbyname(servicename, protocolname)通过服务名获取端口号

servicename: 服务名称(如'http')

protocolname: 协议名称(如'tcp')

端口号整数port = socket.getservbyname('http', 'tcp')
s.getservbyport(port, protocolname)通过端口号获取服务名

port: 端口号整数

protocolname: 协议名称(如'tcp')

服务名字符串service = socket.getservbyport(80, 'tcp')
s.inet_aton(ip_string)将IPv4地址转换为32位打包二进制格式

ip_string:

IPv4地址字符串

打包的二进制数据(4字节)packed = socket.inet_aton('192.168.1.1')
s.inet_ntoa(packed_ip)将32位打包的IPv4地址转换为字符串格式packed_ip: 打包的二进制IP地址IPv4地址字符串ip = socket.inet_ntoa(packed)
s.inet_pton(address_family, ip_str)将IP地址转换为打包二进制格式

address_family: AF_INET或AF_INET6

ip_str: IP地址字符串

打包的二进制数据packed = socket.inet_pton(socket.AF_INET6, '::1')
s.inet_ntop(address_family, packed_ip)将打包的二进制IP地址转换为字符串格式

address_family: AF_INET或AF_INET6 packed_ip: 打包的

二进制IP地址

IP地址字符串

ip=socket.inet_ntop

(socket.AF_INET6, packed)

Socket对象方法

方法描述参数返回值适用协议
bind(address)将socket绑定到地址address: (host, port)元组TCP/UDP
listen(backlog)启动TCP监听backlog: 最大挂起连接数TCP
accept()接受TCP连接(socket, address)元组TCP
connect(address)连接到远程socketaddress: (host, port)元组TCP
connect_ex(address)connect()的扩展版本,出错时返回错误码而非异常address: (host, port)元组错误代码(成功时为0)TCP
send(data)发送TCP数据data: 要发送的字节数据已发送的字节数TCP
recv(bufsize)接收TCP数据bufsize: 最大接收字节数接收到的数据字节TCP
sendall(data)完整发送TCP数据data: 要发送的字节数据无(成功)/抛出异常(失败)TCP
sendto(data, address)发送UDP数据

data: 要发送的字节数据

address: (host, port)元组

已发送的字节数UDP
recvfrom(bufsize)接收UDP数据bufsize: 最大接收字节数(data, address)元组UDP
close()关闭socketTCP/UDP
settimeout(value)设置超时时间(秒)value: 超时时间(浮点数)TCP/UDP
gettimeout()获取超时设置

超时时间(秒),

未设置返回None

TCP/UDP
setsockopt(level, optname, value)设置socket选项

level: 选项级别

optname: 选项名称

value: 选项值

TCP/UDP
getsockopt(level, optname)获取socket选项

level: 选项级别

optname: 选项名称

选项值TCP/UDP
setblocking(flag)设置阻塞或非阻塞模式

flag: True为阻塞,

False为非阻塞

TCP/UDP
getpeername()返回远程地址(ip, port)元组TCP
getsockname()返回socket自己的地址(ip, port)元组TCP/UDP
shutdown(how)关闭连接的一部分

how: SHUT_RD/

SHUT_WR/

SHUT_RDWR

TCP

socketserver模块核心类

描述主要方法返回值
server.TCPServerTCP同步服务器基类serve_forever(): 持续处理请求 handle_request(): 处理单个请求 shutdown(): 停止服务
server.UDPServerUDP同步服务器基类同上同上
server.ThreadingMixIn线程混合类,用于创建多线程服务器与服务器类混合使用
server.ForkingMixIn进程混合类,用于创建多进程服务器与服务器类混合使用
server.BaseRequestHandler请求处理程序基类

handle(): 必须重写的方法,处理请求 setup(): 初始化方法

finish(): 清理方法

asyncio网络编程核心API

API描述参数返回值
asyncio.start_server(client_connected_cb, host, port)创建TCP服务器

client_connected_cb:

客户端连接回调

host: 主机地址

port: 端口号

Server对象
asyncio.open_connection(host, port)创建TCP客户端连接

host: 服务器主机地址

port: 服务器端口号

(reader, writer)元组
asyncio.start_unix_server(client_connected_cb, path)创建Unix域套接字服务器

client_connected_cb: 客户端连接回调

path: 套接字路径

Server对象
asyncio.open_unix_connection(path)创建Unix域套接字客户端连接path: 套接字路径(reader, writer)元组
asyncio.StreamReader.read(n)从流中读取数据n: 要读取的字节数读取的数据(bytes)
asyncio.StreamReader.readline()从流中读取一行读取的行(bytes)
asyncio.StreamWriter.write(data)向流中写入数据data: 要写入的数据(bytes)
asyncio.StreamWriter.drain()等待写入操作完成
asyncio.StreamWriter.close()关闭流

select模块核心API

API描述参数返回值
select.select(rlist, wlist, xlist[, timeout])等待I/O就绪

rlist: 等待读取的对象列表

wlist: 等待写入的对象列表

xlist: 等待异常的对象列表

timeout: 超时时间(秒)

(rready, wready, xready)三元组
select.poll()创建poll对象poll对象
poll.register(fd[, eventmask])注册文件描述符到poll对象

fd: 文件描述符

eventmask: 事件掩码

poll.unregister(fd)从poll对象中取消注册文件描述符fd: 文件描述符
poll.poll([timeout])等待事件timeout: 超时时间(毫秒)[(fd, event), ...]列表

常见常量参数

常量描述
socket.AF_INET2IPv4地址族
socket.AF_INET610IPv6地址族
socket.SOCK_STREAM1TCP协议类型
socket.SOCK_DGRAM2UDP协议类型
socket.SOL_SOCKET1Socket选项级别
socket.SO_REUSEADDR2地址重用选项
socket.SO_KEEPALIVE9保持连接选项
socket.SHUT_RD0关闭接收方向
socket.SHUT_WR1关闭发送方向
socket.SHUT_RDWR2关闭双向连接

参考

  • 官方文档

  • 菜鸟教程 - Python 网络编程

  • 廖雪峰 Python 教程 - TCP/UDP 编程
     


文章转载自:

http://hodPsh8t.tbzcL.cn
http://sTSUTI3E.tbzcL.cn
http://mQRtoTFz.tbzcL.cn
http://s0EBYNOY.tbzcL.cn
http://2uv6QE1Y.tbzcL.cn
http://cG2nY0sY.tbzcL.cn
http://J3hYCDCn.tbzcL.cn
http://cFxAfnoB.tbzcL.cn
http://uquR5hnZ.tbzcL.cn
http://prwcCrnf.tbzcL.cn
http://ybLsj5V4.tbzcL.cn
http://XLrYyYVD.tbzcL.cn
http://qR5klQIu.tbzcL.cn
http://gHS76JiZ.tbzcL.cn
http://JgksAYnG.tbzcL.cn
http://rt3DoRch.tbzcL.cn
http://IfeNvySH.tbzcL.cn
http://y9mIBqz2.tbzcL.cn
http://Fly1MF43.tbzcL.cn
http://cGpkKtZb.tbzcL.cn
http://pn4ewKMt.tbzcL.cn
http://m0Cxe4FW.tbzcL.cn
http://jPxsj6VR.tbzcL.cn
http://HjG8uZzv.tbzcL.cn
http://qCp1jwBp.tbzcL.cn
http://C2cVFE3J.tbzcL.cn
http://Imu9fctV.tbzcL.cn
http://OQVHJcxl.tbzcL.cn
http://clZw4Tgk.tbzcL.cn
http://qSwYlLIp.tbzcL.cn
http://www.dtcms.com/a/377776.html

相关文章:

  • 双token
  • c#基础(一)
  • VMware Workstation 不可恢复错误:(vcpu-1) Exception 0xc0000005 解决方案
  • IndexTTS2.0_ 情感表达与时长可控的自回归零样本语音合成突破
  • Git提交文件提取工具:一键将特定提交的文件导出到指定目录
  • 中间件漏洞详解
  • TC_Motion多轴运动-PID调节
  • Java 学习笔记(进阶篇3)
  • 金蝶云星空 调价表取历史价格
  • TwinCAT3人机界面1
  • C#语言入门详解(18)传值、输出、引用、数组、具名、可选参数、扩展方法
  • 【C++世界之string模拟实现】
  • 打工人日报#20250910
  • LeetCode100-206反转链表
  • function-call怎么训练的,预料如何构建
  • OpenLayers数据源集成 -- 章节四:矢量格式图层详解
  • 220V供电遥测终端 220V供电测控终端 选型
  • 【LLM】Transformer注意力机制全解析:MHA到MLA
  • 三十六、案例-文件上传-阿里云OSS-集成
  • 网编.hw.9.10
  • 4215kg轻型载货汽车变速器设计cad+设计说明书
  • Python数据可视化科技图表绘制系列教程(七)
  • 【 VMware Workstation 提示“虚拟机已在使用”怎么办?一篇文章彻底解决!】
  • WebSocket网络编程深度实践:从协议原理到生产级应用
  • 数字健康新图景:AI健康小屋如何重塑我们的健康生活
  • ⚡ Linux sed 命令全面详解(包括参数、指令、模式空间、保持空间)
  • Codeforces Round 1049 (Div. 2) D题题解记录
  • 视频分类标注工具
  • 【学习】vue计算属性
  • Torch 安装