网络通信代码:解决沾包问题
服务端:
#!\Users\Local\Programs\Python37
# -*- coding: utf-8 -*-
# Author: Hua Wang
# Time:2020/9/16
import socket
import subprocess
import struct
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1', 8892))
phone.listen(3)
print('staring...')
while True: # 建立连接循环
conn, client_addr = phone.accept()
print(client_addr)
while True: # 通信循环
try:
# 1 收命令
cmd = conn.recv(8888)
if not cmd:break # 适用于linux操作系统
# 2执行命令,拿到结果
# obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# stdout = obj.stdout.read()
# stderr = obj.stderr.read()
obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout=obj.stdout.read()
stderr=obj.stderr.read()
# 3 把命令的结果返回给客户端
# 第一步:制作固定长度的报头
header_dic= {
'filename': 'a.text',
'aithor':'WH',
'total_size' :len(stdout)+len(stderr)
}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')
header_length = struct.pack('i',len(header_bytes))
print(header_length)
# 第二步:先发送报头的长度
conn.send(header_length) # 先发送所要接受的报头长度信息
# 第三步 :再发报头
conn.send(header_bytes)
# 第四步:在发送真实的数据
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError: # 适用于windows操作系统
print('断开链接了。。')
break
conn.close()
phone.close()
客户端:
#!\Users\Local\Programs\Python37
# -*- coding: utf-8 -*-
# Author: Hua Wang
# Time:2020/9/16
import socket
import struct
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(('127.0.0.1', 8892))
while True: # 建立通信循环
# 1、发命令
cmd = input('>>: ').strip()
if not cmd: continue
phone.send(cmd.encode('utf-8'))
# 2、拿命令的结果,并打印
# 第一步 先收报头的长度
obj = phone.recv(4)
print(obj)
header_size = struct.unpack('i', obj)[0]
# 第二步 在收报头
header_bytes = phone.recv(header_size)
# 第三步 从报头中解析出对真实数据得描述信息
header_json = header_bytes.decode('utf-8')
header_dic = json.loads(header_json)
print(header_dic)
total_size = header_dic['total_size'] # 2获取数据总长度
# 第四步:接受真实的数据
recv_size = 0
recv_data = b''
while recv_size < total_size:
res = phone.recv(1024)
recv_size += len(res)
recv_data += res
# data=phone.recv(total_size) # todo 为啥不可以直接接受指定长度
print(recv_data.decode('gbk'))
phone.close()