网络聊天工具 - 基于Python开发

网络聊天工具 - 基于Python开发 概述本文档详细介绍了一个基于Python和PyQt5开发的局域网P2P聊天应用的技术架构与实现细节。该应用支持文字聊天、文件传输、视频通话等核心功能,采用TCP/UDP混合协议实现可靠的消息传输和实时的视频流传输。技术栈技术版本用途Python3.11+核心开发语言PyQt55.15+GUI框架SQLite3.x本地数据存储OpenCV4.5+视频采集与编解码NumPy1.20+图像数据处理PyInstaller5.0+应用打包项目结构chat_app/ ├── main.py # 程序入口 ├── main_window.py # 主界面实现 (PyQt5 GUI) ├── network.py # 网络通信模块 (TCP Socket) ├── file_transfer.py # 文件传输模块 (独立TCP端口) ├── video_call.py # 视频通话模块 (UDP协议) ├── database.py # 数据库模块 (SQLite加密存储) ├── config.py # 配置文件 ├── requirements.txt # 依赖清单 ├── chat_records.db # 聊天记录数据库 └── received_files/ # 接收文件存储目录1. Socket 网络通信原理与系统架构设计1.1 Socket通信原理Socket(套接字)是网络通信的端点,本系统使用TCP协议进行可靠的数据传输。TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP Socket通信流程:服务器端 客户端 | | | socket() 创建套接字 | | | | bind() 绑定地址和端口 | | | | listen() 开始监听 | | | | accept() 等待连接 ------------| socket() 创建套接字 | | | recv() --数据-- send() | | | | send() --数据-- recv() | | | | close() 关闭连接 --close() |TCP三次握手建立连接:客户端 服务器 | | |---- SYN J ------------| 第一步:客户端发送SYN | | |--- SYN K, ACK J+1 ----| 第二步:服务器发送SYN+ACK | | |---- ACK K+1 ----------| 第三步:客户端发送ACK | | | 连接建立完成 |1.2 系统架构设计系统采用P2P(点对点)混合架构,每个节点既是服务器也是客户端。这种设计避免了中央服务器的单点故障问题,同时简化了部署流程。┌─────────────────────────────────────────────────────────────┐ │ 用户界面层 (PyQt5) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ 会话列表 │ │ 聊天窗口 │ │ 视频通话窗口 │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ │ 信号/槽机制 ▼ ┌─────────────────────────────────────────────────────────────┐ │ 业务逻辑层 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ NetworkMgr │ │ FileTransfer│ │ VideoCallManager │ │ │ │ 网络管理 │ │ 文件传输 │ │ 视频通话 │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ │ Socket API ▼ ┌─────────────────────────────────────────────────────────────┐ │ 数据存储层 │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ SQLite 加密数据库 (chat_records.db) │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌───────────────┐ │ │ │ │ │ chat_sessions│ │ messages │ │ file_records │ │ │ │ │ └─────────────┘ └─────────────┘ └───────────────┘ │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘1.3 核心模块说明模块文件功能描述配置模块config.py系统配置常量、端口、消息类型定义数据库模块database.pySQLite加密存储、消息记录管理网络模块network.pyTCP Socket服务器/客户端实现文件传输file_transfer.py文件发送/接收、分块传输视频通话video_call.py摄像头采集、视频编解码传输主界面main_window.pyPyQt5 GUI界面实现1.4 端口分配端口用途协议说明8888主通信端口TCP文字消息、控制信令8889视频通话端口UDP视频帧传输8890文件传输端口TCP文件数据传输2. 消息协议设计2.1 消息格式所有消息使用统一的二进制帧格式,包含长度前缀和JSON数据负载:┌─────────────┬─────────────────────────────────────┐ │ 4 bytes │ JSON数据 │ │ 消息长度 │ {type, content, metadata, timestamp}│ └─────────────┴─────────────────────────────────────┘长度字段:使用网络字节序(大端)的4字节无符号整数,表示JSON数据的长度。JSON数据结构:{"type":"TEXT","content":"消息内容","metadata":{"file_size":1024,"file_path":"/path/to/file"},"timestamp":"2024-01-15T10:30:00.123456"}2.2 消息类型定义类型常量说明用途TEXTMSG_TEXT文本消息聊天文字传输FILEMSG_FILE文件消息文件传输通知IMAGEMSG_IMAGE图片消息图片传输通知VIDEO_CALLMSG_VIDEO_CALL视频通话请求发起视频通话VIDEO_ENDMSG_VIDEO_END结束视频通话结束通话通知CONNECTMSG_CONNECT连接通知用户上线通知DISCONNECTMSG_DISCONNECT断开通知用户下线通知USER_LISTMSG_USER_LIST用户列表在线用户列表2.3 消息编码实现classMessageProtocol:"""消息协议类 - 定义消息格式"""@staticmethoddefencode(message_type:str,content:Any,metadata:Dict=None)-bytes:""" 编码消息 消息格式: [4字节长度][JSON数据] """data={'type':message_type,'content':content,'metadata':metadataor{},'timestamp':datetime.now().isoformat()}json_data=json.dumps(data,ensure_ascii=False).encode('utf-8')length=struct.pack('!I',len(json_data))# 网络字节序returnlength+json_data@staticmethoddefdecode(data:bytes)-Dict:"""解码消息"""try:returnjson.loads(data.decode('utf-8'))exceptExceptionase:return{'type':'ERROR','content':str(e)}2.4 粘包处理TCP是流式协议,可能发生粘包现象。系统通过以下机制处理:def_handle_client(self,client_socket:socket.socket,client_ip:str):"""处理客户端消息"""buffer=b''whileself.is_running:data=client_socket.recv(BUFFER_SIZE)buffer+=data# 解析消息(处理可能的粘包)whilelen(buffer)=4:# 读取消息长度msg_len=struct.unpack('!I',buffer[:4])[0]# 检查是否收到完整消息iflen(buffer)4+msg_len:break# 提取完整消息msg_data=buffer[4:4+msg_len]buffer=buffer[4+msg_len:]# 移除已处理数据# 解码并处理消息message=MessageProtocol.decode(msg_data)self.message_callback(message)3. 网络通信实现3.1 服务器端实现SocketServer类实现TCP服务器,负责监听连接请求和处理客户端消息:classSocketServer:"""TCP Socket服务器"""def__init__(self,host:str='0.0.0.0',port:int=DEFAULT_PORT):self.host=host self.port=port self.server_socket=Noneself.is_running=Falseself.clients:Dict[str,socket.socket]={}# IP - socketself.message_callback:Optional[Callable]=Nonedefstart(self):"""启动服务器"""# 1. 创建TCP套接字self.server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 2. 设置端口复用(避免地址已被使用错误)self.server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)# 3. 绑定地址和端口self.server_socket.bind((self.host,self.port))# 4. 开始监听(最大等待队列10)self.server_socket.listen(10)self.is_running=True# 5. 启动接受连接的线程self.server_thread=threading.Thread(target=self._accept_connections,daemon=True)self.server_thread.start()多线程连接处理:def_accept_connections(self):"""接受客户端连接(独立线程运行)"""whileself.is_running:try:self.server_socket.settimeout(1.0)# 非阻塞超时client_socket,address=self.server_socket.accept()client_ip