面试题答案
一键面试设计思路
- 消息头:在每个消息前添加固定长度的消息头,消息头中包含消息体的长度等关键信息。这样接收方可以根据消息头中的长度信息准确知道后续消息体的长度,从而避免粘包和拆包问题。
- 定长包头:确保包头长度固定,便于接收方按固定长度读取包头信息。
- 数据校验:可在消息头或消息尾添加校验和等信息,用于验证消息在传输过程中是否发生错误。
关键代码实现(Python示例)
import socket
import struct
# 定义包头长度
HEADER_LENGTH = 4
def send_message(sock, message):
# 计算消息长度
message_length = len(message)
# 打包消息长度为4字节的二进制数据(大端序)
header = struct.pack('!I', message_length)
# 发送包头
sock.sendall(header)
# 发送消息体
sock.sendall(message.encode('utf-8'))
def receive_message(sock):
# 接收包头
header = sock.recv(HEADER_LENGTH)
if not header:
return None
# 解包包头,获取消息长度
message_length = struct.unpack('!I', header)[0]
# 接收消息体
message = sock.recv(message_length)
if not message:
return None
return message.decode('utf-8')
# 创建TCP socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1', 12345))
server_socket.listen(1)
while True:
client_socket, client_address = server_socket.accept()
message = receive_message(client_socket)
if message:
print(f"Received: {message}")
response = "Message received successfully"
send_message(client_socket, response)
client_socket.close()
在上述代码中:
send_message
函数负责将消息长度打包成固定长度的包头,然后发送包头和消息体。receive_message
函数先接收固定长度的包头,解析出消息体长度,再接收对应长度的消息体。- 服务器端通过
socket
模块监听连接,接收并处理客户端发送的消息,同时给客户端发送响应。