zoukankan      html  css  js  c++  java
  • python 网络编程-03 粘包问题及处理

    粘包问题出现在TCP连接下。
    由于client 端通过 tcp 连接 向 server端发送消息,多条消息之间没有明显的区分,导致server端在接收时,会将前一条消息的 结尾与下一天消息的开头放入一个缓冲区进行接收。
    导致两条数据粘在一起, 称为粘包。

    解决粘包的思路为,在发送一条消息时 将前4个字符设置为消息的长度,让接收端知道消息的长度即可区分不同的消息。

    粘包问题及解决 / pro.py

    import struct
    
    
    def sender(conn, msg: bytes):
        # 计算消息的长度
        pack_head = struct.pack('i', len(msg))
        # 发送消息的长度
        conn.send(pack_head)
        # 发送消息
        conn.send(msg)
    
    
    def receiver(conn) -> str:
        # 获取消息的长度
        length = struct.unpack('i', conn.recv(4))[0]
        print(length)
        # 设置缓冲区大小为1024
        buff_size = 1024
        msg = ''
        while True:
            if length < buff_size:
                #  消息长度小于缓冲区大小  接收数据结束循环
                recv_msg = conn.recv(length)
                msg += recv_msg.decode('utf-8')
                break
            else:
                # 消息长度大于缓冲区大小  
                # 接收缓冲区大小的数据
                # 数据长度减去已经接收的长度
                recv_msg = conn.recv(length)
                length -= buff_size
                msg = recv_msg.decode('utf-8')
    
        return msg
    
    

    server.py

    import socket, subprocess,traceback
    from 粘包问题及解决 import proto
    
    if __name__ == '__main__':
        s = socket.socket()
        s.bind(('127.0.0.1', 8000))
        s.listen()
        while True:
            print('等待连接')
            conn, addr = s.accept()
            while True:
                try:
                    commend = proto.receiver(conn)
                except Exception as e:
                    print('连接异常')
                    conn.close()
                    print(traceback.print_exc())
                    break
                if commend == 'exit':
                    conn.close()
                    break
                obj = subprocess.Popen(commend, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                out = obj.stdout.read()
                err = obj.stderr.read()
                if err:
                    print("err:", err)
                    proto.sender(conn, err)
                else:
                    print("out", out)
                    proto.sender(conn, out)
    

    client.py

    import socket
    from 粘包问题及解决 import proto
    
    if __name__ == '__main__':
        s = socket.socket()
        s.connect(('127.0.0.1', 8000))
        while True:
            cmd = input("> ")
            proto.sender(s, cmd.encode('utf-8'))
            if cmd == 'exit':
                s.close()
                break
            print(proto.receiver(s))
    
    
  • 相关阅读:
    power designer 绘制E-R 图
    git 的证书重新设置,以及如何让git 记住提交的用户名和密码
    weblogic的安装和注意的问题以及在idea怎么用weblogic启动一个web服务
    java的URI和URL到底是什么
    怎么把centos虚拟机zip文件导入vm虚拟机中
    gogole调试请求体的数据怎么知道
    Javascript数据类型——number类型
    Javascript类型——boolean类型
    Javascript数据类型——undefined和null的异同
    第3章,基本概念
  • 原文地址:https://www.cnblogs.com/pythonPath/p/12402021.html
Copyright © 2011-2022 走看看