标签:循环 tar 传输介质 信息 缓冲 input while 数据 lis
黏包现象.
系统缓冲区.
缓冲区的作用?
没有缓冲区:如果你的网络出现短暂的异常或者波动,接收数据就会出现短暂的中断,影响你的下载或者上传的效率.
但是 凡是都是双刃剑,缓冲区解决了上传下载的传输效率的问题,带来了黏包问题.
什么情况下产生黏包
解决黏包的方案
low版
server
import socket
import subprocess
import struct
phone = socket.socket()
phone.bind(('127.0.0.1', 8888))
phone.listen(5)
# 4. 接收连接
print('start')
conn, addr = phone.accept()
while 1:
try:
cmd = conn.recv(1024)
obj = subprocess.Popen(cmd.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
result = obj.stdout.read() + obj.stderr.read()
# print(f'服务端发送的总字节数{len(result)}')
# 1. 制作报头
total_size = len(result)
# 2. 将不固定长度的int类型的报头,转化成固定长度bytes 4个字节
# 将一个数字转化成等长度的bytes类型。
total_size_bytes = struct.pack('i', total_size)
# 3. 发送报头
conn.send(total_size_bytes)
# 4. 发送原数据
conn.send(result)
except ConnectionResetError:
break
conn.close()
phone.close()
client
import socket
import struct
phone = socket.socket()
phone.connect(('127.0.0.1', 8888))
# 发消息
while 1:
cmd = input('>>>').strip()
phone.send(cmd.encode('utf-8'))
# 1. 接收报头
head_bytes = phone.recv(4)
# 2. 将报头反解回int类型
total_size = struct.unpack('i', head_bytes)[0] # 1517
# 3. 循环接收原数据
total_data = b''
while len(total_data) < total_size:
total_data += phone.recv(1024)
print(total_data.decode('gbk'))
# 关机
phone.close()
旗舰版
server
import socket
import subprocess
import struct
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.bind(('127.0.0.1', 8878))
phone.listen(5)
while 1:
conn, client_addr = phone.accept()
print(client_addr)
while 1:
try:
cmd = conn.recv(1024)
ret = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
correct_msg = ret.stdout.read()
error_msg = ret.stderr.read()
# 1 制作固定报头
total_size = len(correct_msg) + len(error_msg)
header_dict = {
'md5': 'fdsaf2143254f',
'file_name': 'f1.txt',
'total_size': total_size,
}
header_dict_json = json.dumps(header_dict) # str
bytes_headers = header_dict_json.encode('utf-8')
header_size = len(bytes_headers)
header = struct.pack('i', header_size)
# 2 发送报头长度
conn.send(header)
# 3 发送报头
conn.send(bytes_headers)
# 4 发送真实数据:
conn.send(correct_msg)
conn.send(error_msg)
except ConnectionResetError:
break
conn.close()
phone.close()
client
import socket
import struct
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(('127.0.0.1', 8878))
while 1:
cmd = input('>>>').strip()
if not cmd: continue
phone.send(cmd.encode('utf-8'))
# 1,接收固定报头
header_size = struct.unpack('i', phone.recv(4))[0]
# 2,解析报头长度
header_bytes = phone.recv(header_size)
header_dict = json.loads(header_bytes.decode('utf-8'))
# 3,收取报头
total_size = header_dict['total_size']
# 3,根据报头信息,接收真实数据
recv_size = 0
res = b''
while recv_size < total_size:
recv_data = phone.recv(1024)
res += recv_data
recv_size += len(recv_data)
print(res.decode('gbk'))
phone.close()
标签:循环 tar 传输介质 信息 缓冲 input while 数据 lis
原文地址:https://www.cnblogs.com/hql1117/p/11201832.html