粘包--day31

粘包问题

struct
将字节转换为二进制数据
https: // docs.python.org / 3 /
可以查找内置模块的用法

# 给予网络传输文件的方法

# 1.发送额外信息长度
# 2.发送额外信息
# 3.发送真实数据长度
# 4.发送真实数据

# -------------------------------------客户端--------------------------------------

import socket
import subprocess
import struct
import datetime
import json

server = socket.socket()

server.bind(("127.0.0.1", 9090))

server.listen()

while True: # 循环接收连接
client, addr = server.accept()
while True:
try:
# 接收命令
cmd = client.recv(1024).decode("utf-8")
p = subprocess.Popen(cmd, shell=True, stdout=-1, stderr=-1) # 调用subprocess模块运行cmd命令

data = p.stdout.read() # --- data与err_data 都是采用的系统编码 windows是GBK
err_data = p.stderr.read()

print("数据长度:%s" % (len(data) + len(err_data)))

length = len(data) + len(err_data) # 计算真实数据长度

# 在发送数据之前发送额外的信息
# t = "{执行时间:%s 真实数据长度:%s" % (datetime.datetime.now(),length)
# 把要发送的数据先存到字典中
t = {}
t["time"] = str(datetime.datetime.now())
t["size"] = length
t["filename"] = "a.mp4" # 可以用来添加报头信息

# 利用json吧字典转换成为字符串,再用srtuct.pack将字符串转换成为二进制
t_json = json.dumps(t) # 得到json格式字符串
t_data = t_json.encode("utf-8") # 将json转成了二进制
t_length = struct.pack("i", len(t_data)) # 将二进制计算打包为 4位数

# ***解释*** 用struct.pack来将文件头计算为4位的长度 在用struct.unpack将文件计算为原来的长度就得到了 文件头的长度在接收文件头

client.send(t_length) # 1.先发送额外信息的长度

client.send(t_data) # 2.发送额外信息

client.send(data) # 3.发送真实信息的长度
client.send(err_data) # 4.发送真实数据

except ConnectionResetError:
client.close()
print("连接中断......")
break

# --------------------------------------服务端-----------------------------------

import socket
import struct
import socket
import json

c = socket.socket()

c.connect(("127.0.0.1", 9090))

while True:
cmd = input(">>:")
if not cmd:
print("命令不能为空")
continue

c.send(cmd.encode("utf-8")) # 指定输入信息的编码格式

# 1.接收的是额外信息的长度
length = c.recv(4)
len_data = struct.unpack("i", length)[0] # 转换为整型

# 2.接收额外信息
t_data = c.recv(len_data)
print(t_data.decode("utf-8"))

json_dic = json.loads(t_data.decode("utf-8"))
#用json反序列化出字典
print("执行时间:%s" % json_dic["time"])

data_size = json_dic["size"] # 得到数据长度

# 3.接收真实数据
all_data = b"" # 存储已接收数据
rcv_size = 0 # 已接收长度

# 接收真实数据
# 循环接收 直到 接收到的长度等于总长度
while rcv_size < data_size:
data = c.recv(1024)
rcv_size += len(data)
all_data += data

print("接收长度%s" % rcv_size)
print(all_data.decode("gbk"))
posted @ 2018-12-26 16:07  WenChen-0o0  阅读(126)  评论(0编辑  收藏  举报