如何在AES加密Python聊天服务器中用Python 2 Socket分送多字符串?
嘿,针对你的Python 2 Socket发送多个字符串的需求,结合你正在开发的AES加密聊天服务器场景,我给你整理了两个实用的方案——毕竟Socket是字节流,接收端得准确区分哪段是一个完整的消息才行对吧?
在Python 2 Socket中发送多个字符串的实现方案
咱先明确核心问题:Socket本身是基于流式传输的,没有天然的消息边界,所以要发送多个字符串,关键是给每条消息加上“标识”,让接收端能精准拆分。下面两种方法都适配你的加密聊天场景:
方法一:用分隔符标记消息边界
这是最简单的方式,给每个加密后的字符串末尾加一个不会出现在消息内容里的特殊分隔符(比如\r\n,或者自定义的特殊字符),接收端读取字节流时,按分隔符拆分就行。
客户端发送示例(结合AES加密)
假设你已经写好了AES加密函数aes_encrypt(plain_text, key),返回加密后的字符串:
import socket def send_multiple_messages(sock, messages, aes_key): for msg in messages: # 先把明文消息加密 encrypted_msg = aes_encrypt(msg, aes_key) # 给加密后的消息加个分隔符,这里用\r\n(得确保加密内容里不会有这个组合) msg_with_delimiter = encrypted_msg + "\r\n" # Python 2里str默认是字节,直接发送就行;如果是unicode的话要先encode成utf-8 sock.send(msg_with_delimiter) # 用法示例 client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_sock.connect(('localhost', 8080)) my_client_key = "my_secure_key_123" messages_to_send = ["Hey everyone!", "This is encrypted!", "See you later!"] send_multiple_messages(client_sock, messages_to_send, my_client_key)
服务器/接收端读取示例
def receive_messages(sock): buffer = "" while True: # 每次读1024字节 data = sock.recv(1024) if not data: # 连接断开了 break # 把读到的内容拼到缓冲区里 buffer += data # 循环拆分缓冲区里的消息 while "\r\n" in buffer: # 拆出第一条消息和剩下的缓冲区内容 msg, buffer = buffer.split("\r\n", 1) # 这里拿到的是加密后的消息,直接广播给其他客户端就行 broadcast_to_clients(msg) def broadcast_to_clients(encrypted_msg): # 这里实现你的广播逻辑 print(f"Broadcasting encrypted message: {encrypted_msg}")
⚠️ 注意:如果你的AES加密后的内容可能包含\r\n(或者你选的其他分隔符),那这种方法就会拆错消息,这时候就用下面的方法二,更可靠。
方法二:先发消息长度,再发消息内容
这种方法更稳妥,先发送消息的字节长度,接收端先读取长度值,再根据长度读取对应字节数的消息内容——完全不受消息内容影响,特别适合加密场景(因为加密后的内容可能包含任意字节)。
客户端发送示例(结合AES加密)
我们用struct模块把长度打包成固定4字节的大端整数,确保跨平台兼容性:
import socket import struct def send_single_message(sock, encrypted_msg): # 先获取加密后消息的字节长度 msg_length = len(encrypted_msg) # 把长度打包成4字节的大端整数 packed_length = struct.pack('!I', msg_length) # 先发送长度,再发送消息内容 sock.send(packed_length) sock.send(encrypted_msg) def send_multiple_messages(sock, messages, aes_key): for msg in messages: encrypted_msg = aes_encrypt(msg, aes_key) send_single_message(sock, encrypted_msg) # 用法和之前类似 client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_sock.connect(('localhost', 8080)) my_client_key = "my_secure_key_123" messages_to_send = ["Hey everyone!", "This is encrypted!", "See you later!"] send_multiple_messages(client_sock, messages_to_send, my_client_key)
服务器/接收端读取示例
import struct def receive_single_message(sock): # 先读取4字节的长度数据 length_data = sock.recv(4) if not length_data: # 连接断开 return None # 解包得到消息长度 msg_length = struct.unpack('!I', length_data)[0] # 读取对应长度的消息内容 encrypted_msg = sock.recv(msg_length) # 防止一次读不完,循环读到足够的字节数 while len(encrypted_msg) < msg_length: encrypted_msg += sock.recv(msg_length - len(encrypted_msg)) return encrypted_msg def receive_messages(sock): while True: encrypted_msg = receive_single_message(sock) if not encrypted_msg: break broadcast_to_clients(encrypted_msg) def broadcast_to_clients(encrypted_msg): print(f"Broadcasting encrypted message: {encrypted_msg}")
针对你的聊天服务器的额外小建议
- 因为每个客户端有自己的密钥,服务器只需要负责转发加密后的消息就行,不用解密,这样更安全,也减少服务器的计算压力。
- Python 2里要注意字符串和unicode的区别:如果你的AES加密函数返回的是unicode字符串,记得用
encode('utf-8')转成字节流再发送;如果已经是str类型(字节),直接发送就好。 - 记得加异常处理:比如Socket连接断开、发送失败这些情况,用try-except块包裹,保证程序不会轻易崩溃。
内容的提问来源于stack exchange,提问作者TimD1




