python 中黏包的处理(实现简单的ssh)

python 中黏包的处理(实现简单的ssh)
黏包的处理
  1. 首先黏包就是连续发送两个数据,且中间没有阻塞时,操作系统自动将两次数据打包到一起发送
  2. 黏包的发生会造成数据传输后,数据丢失,不完整,接收到数据不能使用
  3. 通过阻塞解决黏包问题(影响效率)
  4. 通过添加数据长度解决黏包问题(常用解决方式,如下ssh的实例)
ssh的实例
  1. 服务器端代码如下:
import socket
import subprocess #使用cmd命令的模块
import struct #压缩包的模块,将整形数字压缩成4个字节
#ret=struct.pack("i",1211)#i为整数模式,最小-2147483648,最大压缩2147483647,压缩后为4个字节

ssh_Server = socket.socket()
ssh_Server.bind(('127.0.0.1',8000))
ssh_Server.listen(5)
while 1:
    print('等待连接')
    conn,addr = ssh_Server.accept()
    print('连接成功')
    while 1:
        try:
            cmd = conn.recv(1024).decode('gbk') #接受客户端输入的字符串形式的cmd命令
            #在服务器端实现字符串形式的cmd命令,并获取到结果,stderr为错误命令结果,stdout为正确命令结果
            ret = subprocess.Popen(cmd,
                                   shell = True,
                                   stderr = subprocess.PIPE,
                                   stdout = subprocess.PIPE,
                                    )
            err = ret.stderr.read()#获取错误命令结果的字节,(windows默认gbk编码)
            out = ret.stdout.read()#获取正确命令结果的字节


            if err:#如果错误名存在值,说明客户端输入的是错误的cmd命令,则返回错误信息
                print(len(err))#显示错误信息字节长度
                len_err = struct.pack("i", len(err))#将错误信息字节长度压缩成4个字节
                conn.send(len_err)#发给客户端要接受的数据长度,方便客户端接受数据
                conn.send(err)#发给客户端提示错误的数据信息
            else:
                print(len(out))#显示正确信息字节长度
                len_out = struct.pack("i", len(out))#将正确信息字节长度压缩成4个字节
                conn.send(len_out)
                conn.send(out)#发给客户端提示错误的数据信息
        except Exception as e:
            print('连接已断开')
            break
  1. 客户端代码如下:
import socket
import struct
ssh_Client = socket.socket()
ssh_Client.connect(('127.0.0.1', 8000))
while 1:
    cmd = input('请输入命令:')#输入字符串形式的cmd命令
    ssh_Client.send(cmd.encode('gbk'))#将字符串形式的命令转换成字节(Windows中cmd编码默认gbk)
    len_data1 = ssh_Client.recv(4)#先接受接下来要接受数据的具体长度
    len_data = struct.unpack("i",len_data1)[0]#解压后获取int型数据的具体长度
    print(len_data)#输出接下来要接受的数据长度
    len_res = 0#初始化接受数据总长
    res=b""#初始化接受的数据(字节)
    while len_res < len_data:#判断已经获取的总长是否小于数据总长,如果小于继续获取
        data = ssh_Client.recv(1024)#每次接受1024字节数据
        res = res + data#将数据累加到总的数据中
        len_res = len_res + len(data)#将已经获取的数据长度累加
    print(res.decode('gbk'))#将获取的数据解码输出

运行的效果图:
客户端
服务器端

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值