模拟ssh的远程网络传输
粘包产生的原因分析:
第一点:客户端向服务端发起命令请求,服务端接受命令请求,并返回对应的信息,如果信息过大,客户端一次接受不了,那么下一次请求依然返回
上一个命令的内容,就出现了粘包的情况。
第二点:发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包)
所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。
发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样做,虽然节省了时间,但是发出的包却粘在了一起,造成粘包现象。
简单点的报头(有注释)
- from socket import * # socket里面很多功能用得到,属于特殊情况
- import subprocess
- import struct
- server=socket(AF_INET,SOCK_STREAM) # 生成套接字,绑定ip_port,服务端处于倾听状态
- server.bind(('127.0.0.1',8080))
- server.listen(5)
- while True:
- conn,client_addr=server.accept() # 套接字和绑定的ip_port
- print('新的客户端',client_addr)
- while True: # 下面的不循环结束不会进入下一个客户端
- try:
- cmd=conn.recv(1024) # cmd=b'dir' # 命令一般不会超过1024 不用管
- if len(cmd) == 0:break
- # 运行系统命令 为什么不用system 因为system???
- obj=subprocess.Popen(cmd.decode('utf-8'), # 字节解压成字符串
- shell=True,
- stderr=subprocess.PIPE,
- stdout=subprocess.PIPE
- )
- stdout=obj.stdout.read()# 读出管道里数据 顺序不要乱 先stdout 然后stderr
- stderr=obj.stderr.read()
- #1、先制作报头(固定长度)
- total_size=len(stdout) + len(stderr) # 数据的总长度(整型)
- header=struct.pack('i',total_size) # 把数据的长度按照i格式包装为固定的四个字节的报头
- #2、先发送固定长度的报头
- conn.send(header) # 为什么能解决粘包问题?因为把报头固定为四个字节,接受的时候固定接受
- #3、再发送真实的数据
- conn.send(stdout)
- conn.send(stderr)
- except ConnectionResetError:
- break
- conn.close()
服务端
- from socket import *
- import struct
- client=socket(AF_INET,SOCK_STREAM)
- client.connect(('127.0.0.1',8080))
- while True:
- cmd=input('>>: ').strip()
- if len(cmd) == 0:continue
- client.send(cmd.encode('utf-8'))
- #1、先收固定长度的报头
- header=client.recv(4) # 先接收固定长度的报头
- #2、从报头中解析出对数据的描述信息
- total_size=struct.unpack('i',header)[0] # 按照i格式解析出报头的数据信息,解析出来是一个元组(a,)形式,取第一个
- #3、再收真实的数据
- recv_size=0 # 应用层接受数据,初始数据为0
- res=b''
- while recv_size < total_size : # 接受数据小于传送过来的数据时,循环会一直进行下去
- data=client.recv(1024)
- res+=data
- recv_size+=len(data)
- print(res.decode('gbk'))
客户端
复杂一点的报头(有注释)
- from socket import *
- import subprocess
- import struct
- import json
- server=socket(AF_INET,SOCK_STREAM)
- server.bind(('127.0.0.1',8080))
- 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
- # 运行系统命令
- obj=subprocess.Popen(cmd.decode('utf-8'),
- shell=True,
- stderr=subprocess.PIPE,
- stdout=subprocess.PIPE
- )
- stdout=obj.stdout.read()
- stderr=obj.stderr.read()
- #先制作报头
- header_dic={ # 报头信息 包含文件名 文件大小 hash值
- 'filename':'a.txt',
- 'total_size':len(stdout) + len(stderr),
- 'hash':'xasf123213123'
- }
- header_json=json.dumps(header_dic) # 将包含报头信息的字典存成字符串格式
- header_bytes=header_json.encode('utf-8') # 字符串编码成字节形式
- print(header_json,type(header_json))
- #1、先把报头的长度len(header_bytes)打包成4个bytes,然后发送
- conn.send(struct.pack('i',len(header_bytes)))
- #2、发送报头
- conn.send(header_bytes)
- #3、再发送真实的数据
- conn.send(stdout)
- conn.send(stderr)
- except ConnectionResetError:
- break
- conn.close()
服务端
- from socket import *
- import struct
- import json
- client=socket(AF_INET,SOCK_STREAM)
- client.connect(('127.0.0.1',8080))
- while True:
- cmd=input('>>: ').strip()
- if len(cmd) == 0:continue
- client.send(cmd.encode('utf-8'))
- #1、先收4个字节,该4个字节中包含报头的长度
- header_len=struct.unpack('i',client.recv(4))[0]
- print(client.recv(4))
- print(header_len)
- #2、再接收报头
- header_bytes=client.recv(header_len)
- #从报头中解析出想要的内容
- header_json=header_bytes.decode('utf-8')
- header_dic=json.loads(header_json)
- print(header_dic)
- total_size=header_dic['total_size']
- #3、再收真实的数据
- recv_size=0
- res=b''
- while recv_size < total_size :
- data=client.recv(1024)
- res+=data
- recv_size+=len(data)
- print(res.decode('gbk'))
客户端
模拟ssh的远程网络传输的更多相关文章
- ssh 中 远程文件传输
scp 命令是 SSH 中最方便有用的命令了,试想,在两台服务器之间直接传送文件,仅仅用 scp 一个命令就完全解决了. 你可以在一台服务器上 以 root 身份运行 #scp servername: ...
- golang通过ssh实现远程文件传输
使用ssh远程操作文件, 主要是创建ssh, 直接上代码 import ( "fmt" "github.com/pkg/sftp" "golang.o ...
- 网络编程 - 1.简单的套接字通信/2.加上通信循环/3.bug修复/4.加上链接循环/5.模拟ssh远程执行命令
1.简单的套接字通信 服务端 ''' 服务端 接电话 客户端 打电话 1.先启动服务端 2.服务端有两种套接字 1.phone 用来干接收链接的 2.conn 用来干收发消息的 ''' import ...
- 网络编程之模拟ssh远程执行命令、粘包问题 、解决粘包问题
目录 模拟ssh远程执行命令 服务端 客户端 粘包问题 什么是粘包 TCP发送数据的四种情况 粘包的两种情况 解决粘包问题 struct模块 解决粘包问题 服务端 客户端 模拟ssh远程执行命令 服务 ...
- [Python 网络编程] TCP、简单socket模拟ssh (一)
OSI七层模型(Open System Interconnection,开放式系统互联) 应用层 网络进程访问应用层: 为应用程序进程(例如:电子邮件.文件传输和终端仿真)提供网络服务: 提供用户身份 ...
- 模拟ssh远程执行命令,粘包问题,基于socketserver实现并发的socket
06.27自我总结 1.模拟ssh远程执行命令 利用套接字编来进行远程执行命令 服务端 from socket import * import subprocess server = socket(A ...
- Python 简单socket模拟ssh
OSI七层模型(Open System Interconnection,开放式系统互联) 应用层 表示层 回话层 传输层 tcp,udp 网络层 ip,icmp 数据链路层 mac地址 物理层 物理网 ...
- Linux基础命令介绍七:网络传输与安全 wget curl rsync iptables
本篇接着介绍网络相关命令:wget 文件下载工具.curl 网络数据传输工具.rsync 文件传输工具等. 本篇接着介绍网络相关命令 1.wget 文件下载工具 wget [option]... [U ...
- mac ssh,mac xshell,xshell替代,ssh客户端,ssh工具,远程桌面加速
下载地址 Windows版下载地址:http://www.hostbuf.com/downloads/finalshell_install.exe Mac版,Linux版安装及教程:http://ww ...
随机推荐
- Uva 3902 Network
题目大意: 在非叶子节点上安装最少的服务器使得,每个叶子节点到服务器的距离不超过k. 贪心+图上的dfs. 先从深度最大的叶子节点开始找.找到父节点后再用这个父节点进行扩充. /* ********* ...
- POJ3984 迷宫问题 —— BFS
题目链接:http://poj.org/problem?id=3984 迷宫问题 Time Limit: 1000MS Memory Limit: 65536K Total Submissions ...
- YTU 2429: C语言习题 学生成绩输入和输出
2429: C语言习题 学生成绩输入和输出 时间限制: 1 Sec 内存限制: 128 MB 提交: 1897 解决: 812 题目描述 编写一个函数print,打印一个学生的成绩数组,该数组中有 ...
- docker hub下载慢解决方法 使用daocloud的mirror
见:http://blog.csdn.net/dingsai88/article/details/52638758
- 设置linux服务器下开放端口
查询 netstat -anp 所有开放端口信息 二.关闭端口号: iptables -A OUTPUT -p tcp --dport 端口号-j DROP 三.打开端口号: iptables -A ...
- POJ1113:Wall (凸包:求最小的多边形,到所有点的距离大于大于L)
Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the ...
- UVA140 剪枝
题目 分析:这个题的数据范围很小,直接打印全排列去判断也能过,但是这里存在两个剪枝,第一个,如果当前的距离已经大于前面距离的最小值,则剪枝,还有一个就是如果与当前结点相连的边数大于等于前面距离的最小值 ...
- redhat 关机注销命令详解
一.注销,关机,重启 注销系统的logout命令 1,Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可: [root@localhost root]# ...
- Bootstrap-CSS:代码
ylbtech-Bootstrap-CSS:代码 1.返回顶部 1. Bootstrap 代码 Bootstrap 允许您以两种方式显示代码: 第一种是 <code> 标签.如果您想要内联 ...
- WaveNet: 原始音频生成模型
官方博客 WaveNet: A Generative Model for Raw Audio paper地址:paper Abstract WaveNet是probabilistic and auto ...