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

发布于:2025-09-11 ⋅ 阅读:(20) ⋅ 点赞:(0)

目录

引言

一、 网络编程基础

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 = host
        self.port = port
        self.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)
                break
    
    def 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) 连接到远程socket address: (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() 关闭socket TCP/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.TCPServer TCP同步服务器基类 serve_forever(): 持续处理请求 handle_request(): 处理单个请求 shutdown(): 停止服务
server.UDPServer UDP同步服务器基类 同上 同上
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_INET 2 IPv4地址族
socket.AF_INET6 10 IPv6地址族
socket.SOCK_STREAM 1 TCP协议类型
socket.SOCK_DGRAM 2 UDP协议类型
socket.SOL_SOCKET 1 Socket选项级别
socket.SO_REUSEADDR 2 地址重用选项
socket.SO_KEEPALIVE 9 保持连接选项
socket.SHUT_RD 0 关闭接收方向
socket.SHUT_WR 1 关闭发送方向
socket.SHUT_RDWR 2 关闭双向连接

参考


网站公告

今日签到

点亮在社区的每一天
去签到