• Python socket粘包问题(初级解决办法)


    server端配置:

    import socket,subprocess,struct
    from   socket import *
    server=socket(AF_INET,SOCK_STREAM)
    server.bind(('127.0.0.1',8080))
    server.listen(5)
    
    while True:
        conn,client_addr=server.accept()
        while True:
            try:
                cmd=conn.recv(1024)
                if len(cmd) == 0:break
                obj=subprocess.Popen(
                    cmd.decode('utf-8'),
                    shell=True,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                )
                out=obj.stdout.read()  #bytes类型
                err=obj.stderr.read()
                print(len(out+err))
    
                # 解决粘包问题的步骤,先发型数据的长度
                total_size=len(out)+len(err)  #数据类型,1.变为bytes类型 2.还是个固定长度
    
                #1.制作固定长度的包头
                header=struct.pack('i',total_size)
    
                #2.发送报头
                conn.send(header)
    
                #固定数据报的head头的大小(自定义数据)
    
                #下面是发送真是的数据
                # conn.send(out+err)
                #2个包是一起发过去的,因为间隔短
                conn.send(out)
                conn.send(err)
    
                #发过去的整体是一个数据报=报头+数据部分
    
    
            except ConnectionResetError:
                break
        conn.close()
    
    server.close()

    client端配置:

    import socket
    import socket,struct
    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(('127.0.0.1',8080))
    while True:
        cmd=input('输入执行的命令:')
        if len(cmd) == 0: continue
        client.send(cmd.encode('utf-8'))
        #1.先收固定长度的的包头默认stuck就是固定了长度为4
        header=client.recv(4)    #第二次再收不是下一个包头,是上次命令的残留
        #2.解析包头
        total_size=struct.unpack('i',header)[0]  #拿到的是个元祖,元祖的0就是这个长度值
        print(total_size)
        #3.根据包头内的信息,收取真实数据
        # client.recv(total_size)   因为现实数据量太大的时候就不行,所以考虑while循环
    
        #思考如果数据大,total_size数据会特别大就会直接报错
        #为了解决输入较大程序,定义一个小的变量,循环一点点就去收
        recv_size=0
        res=b''
        while recv_size < total_size:
            recv_data=client.recv(1024)  #recv_data是bytes类型,是唯一真实的值,有多少就会收多少
            res+=recv_data
            recv_size+=len(recv_data)
    
        print(res.decode('gbk'))
    
    
    client.close()
  • 相关阅读:
    触发器
    新登录用户的次日成功的留存率
    获取薪水第二多的
    找到薪水比经理高的员工
    成绩排名
    exists 和 in
    sum+case 计数
    前N个员工的salary累计和
    员工的薪水按照salary进行按照1N的排名,相同salary并列
    洛谷2678 跳石头
  • 原文地址:https://www.cnblogs.com/yangzhizong/p/9281343.html
Copyright © 2020-2023  润新知