您的位置:首页 > 其它

基于ssh实现远程执行命令:解决粘包问题终极版

2020-01-12 12:29 459 查看
# 服务端必须满足至少三点:
# 1. 绑定一个固定的ip和port
# 2. 一直对外提供服务,稳定运行
# 3. 能够支持并发

解决粘包问题的大致思路解决方法:
  首先制作报头
  先获取报头的长度,然后将报头的长度利用struct 模块pack 转化成固定长度的字符串发过去
  对方接收这个固定长度的编码,利用struct 模块 unpack获取报头的长度,然后再接收这个报头的长度,得到报头
  得到报头之后再破解报头中的信息,得到正文的长度格式等具体的信息,如果很大,就用一个循环不断的接收和拼接这个正文,
  最终获取到正文



###服务端程序


from socket import *
import subprocess
import struct
import json

server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8081))
server.listen(5)

# 链接循环
while True:
conn, client_addr = server.accept()
print(client_addr)

# 通信循环
while True:
try:
cmd = conn.recv(1024) # cmd=b'dir'
if len(cmd) == 0: break # 针对linux系统
obj = subprocess.Popen(cmd.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
# 1. 先制作报头
header_dic = {
'filename': 'a.txt',
'md5': 'asdfasdf123123x1',
'total_size': len(stdout) + len(stderr)
}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')

# 2. 先发送4个bytes(包含报头的长度)
conn.send(struct.pack('i', len(header_bytes)))
# 3 再发送报头
conn.send(header_bytes)

# 4. 最后发送真实的数据
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break

conn.close()

server.close()


##客户端程序

from socket import *
import struct
import json

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8081))

# 通信循环
while True:
cmd = input('>>: ').strip()
if len(cmd) == 0: continue
client.send(cmd.encode('utf-8'))
# 1. 先收4bytes,解出报头的长度
header_size = struct.unpack('i', client.recv(4))[0]

# 2. 再接收报头,拿到header_dic
header_bytes = client.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']

# 3. 接收真正的数据
cmd_res = b''
recv_size = 0
while recv_size < total_size:
data = client.recv(1024)
recv_size += len(data)
cmd_res += data

print(cmd_res.decode('gbk'))

client.close()

转载于:https://www.cnblogs.com/1832921tongjieducn/p/11352573.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
diaowei6622 发布了0 篇原创文章 · 获赞 0 · 访问量 140 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: