Python 解决粘包的问题

客户端

import socket
import struct

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone.connect(('127.0.0.1',9909))

while True:
    #1、发命令
    cmd=input('>>: ').strip() #ls /etc
    if not cmd:continue
    phone.send(cmd.encode('utf-8'))

    #2、拿命令的结果,并打印

    #第一步:先收报头
    header=phone.recv(4)

    #第二步:从报头中解析出对真实数据的描述信息(数据的长度)  解包
    total_size=struct.unpack('i',header)[0]

    #第三步:接收真实的数据
    recv_size=0
    #我接受都是bytes类型
    recv_data=b''
    #就一直收
    while recv_size < total_size:
        res=phone.recv(1024) #1024是一个坑
        recv_data+=res
        #收的长度是res  是真实数据量
        recv_size+=len(res)

    print(recv_data.decode('utf-8'))

phone.close()

服务端

import socket
import subprocess
import struct

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',9909)) #0-65535:0-1024给操作系统使用
phone.listen(5)

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

    while True: #通信循环
        try:
            #1、收命令
            cmd=conn.recv(8096)
            if not cmd:break #适用于linux操作系统

            #2、执行命令,拿到结果
            obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

            stdout=obj.stdout.read()
            stderr=obj.stderr.read()

            #3、把命令的结果返回给客户端
            #第一步:制作固定长度的报头  
            total_size = len(stdout) + len(stderr)
            
            #打包
            header=struct.pack('i',total_size)

            #第二步:把报头发送给客户端
            conn.send(header)

            #第三步:再发送真实的数据
            conn.send(stdout)
            conn.send(stderr)

        except ConnectionResetError: #适用于windows操作系统
            break
    conn.close()

phone.close()



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟伟哦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值