python中使用socket与struct模块避免文件传输粘包(Sticky Packet)
避免粘包:避免连续的两个文件连续上传因为界限不清导致存储错位
将两个文件的字节数提前通过struct模块发送到服务端,根据服务端进行按需停止接收。
服务端
#接收文件大小并循环接收内容
import socket
import struct
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 9999))
server.listen(5)
conn,addr = server.accept()
#接收文件1
#接收内容1字节
str_scan = conn.recv(4)
str_byte = struct.unpack('i',str_scan)[0]
#接收内容1
has_receive_byte = 0
has_receive_connect = b''
while True:
#判断是否超过接收内容
#判断接收字节数是否小于1024
length = str_byte-has_receive_byte
if length < 1024:
hsb = str_byte-has_receive_byte
else:
hsb = 1024
data = conn.recv(hsb)
has_receive_connect += data
has_receive_byte += len(data)
#如果接收内容等于
if has_receive_byte == str_byte:
break
print(has_receive_connect.decode())
#接收文件2
str2_scan = conn.recv(4)
str2_byte = struct.unpack('i',str2_scan)[0]
data = conn.recv(str2_byte)
print(data.decode())
conn.close()
客户端
#连续发送两条消息
import socket
import struct
#对象化
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 9999))
#写明发送内容并检测字节数
str_connect = '我大概是'.encode('utf-8')
str1_connect = '测试的'.encode('utf-8')
#发送1的字节和内容
scan_byte = struct.pack('i', len(str_connect))
client.sendall(scan_byte)
client.sendall(str_connect)
#发送2的字节和内容
scan1_byte = struct.pack('i', len(str1_connect))
client.sendall(scan1_byte)
client.sendall(str1_connect)