手把手教你设计并实现Linux环境下的自定义通信协议,彻底搞懂序列化和反序列化
在网络编程中,协议是通信双方约定的数据交换格式。虽然HTTP、JSON等通用协议使用广泛,但在Linux自定义协议场景下,我们往往需要更高效、更紧凑的通信方式。例如,嵌入式系统、游戏服务器、实时数据传输等,都需要量身定制的协议来减少开销、提升性能。
协议设计包括定义字段类型、顺序、边界和校验方式。序列化是将内存中的对象(如结构体、字典)转换为字节流的过程,而反序列化则是其逆过程。这两个步骤是自定义协议的核心,直接决定了通信的效率和可靠性。
以下示例在Linux终端运行,使用Python内置的socket和struct库,演示一个简单的登录认证协议。协议格式如下:
[用户名长度: 4字节][用户名字节][密码长度: 4字节][密码字节] 这种TLV(Type-Length-Value)变体在Linux自定义协议中非常常见。
import socketimport structdef recv_all(sock, n): data = b"" while len(data) < n: packet = sock.recv(n - len(data)) if not packet: return None data += packet return datadef deserialize(data): # 反序列化:解析用户名和密码 name_len = struct.unpack("!I", data[:4])[0] name = data[4:4+name_len].decode() pass_len = struct.unpack("!I", data[4+name_len:8+name_len])[0] password = data[8+name_len:8+name_len+pass_len].decode() return name, passwordserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind(("0.0.0.0", 8888))server.listen(5)print("服务器启动,等待连接...")while True: client, addr = server.accept() print(f"连接来自 {addr}") # 先接收4字节用户名长度 raw_len = recv_all(client, 4) if not raw_len: client.close() continue name_len = struct.unpack("!I", raw_len)[0] # 接收用户名字节 name_data = recv_all(client, name_len) if not name_data: client.close() continue # 接收4字节密码长度 raw_pass_len = recv_all(client, 4) if not raw_pass_len: client.close() continue pass_len = struct.unpack("!I", raw_pass_len)[0] pass_data = recv_all(client, pass_len) if not pass_data: client.close() continue name = name_data.decode() password = pass_data.decode() print(f"收到登录信息:用户名={name}, 密码={password}") client.send(b"OK") client.close() import socketimport structdef serialize(name, password): # 序列化:将用户名和密码打包成字节流 name_bytes = name.encode() pass_bytes = password.encode() return struct.pack("!I", len(name_bytes)) + name_bytes + struct.pack("!I", len(pass_bytes)) + pass_bytesclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect(("127.0.0.1", 8888))data = serialize("alice", "123456")client.send(data)response = client.recv(1024)print("服务器响应:", response.decode())client.close() 在Linux终端中分别运行服务端和客户端:
# 终端1python3 server.py# 终端2python3 client.py 你将看到服务端打印出用户名和密码,说明序列化和反序列化成功。
本文展示了最基础的协议设计,实际应用中还需考虑:
struct.pack("!I", ...)统一为网络字节序(大端)。掌握Linux自定义协议和序列化反序列化,你将能随心所欲地设计高效通信系统。继续深入学习协议设计模式,为成为网络编程高手打下坚实基础。
—— 适合小白的Linux协议教程
本文由主机测评网于2026-03-08发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20260329392.html