zoukankan      html  css  js  c++  java
  • 粘包现象和解决方法

    一.缓冲区

      缓冲区:将程序和网络解耦(类似于cpu和硬盘需要内存来缓冲一样)

      输入缓冲区

      输出缓冲区

    二.subprocess和struct模块的简单认识  

    import subprocess
    
    sub_obj = subprocess.Popen(
         "dir",                                       # cmd指令
         shell=True,
        stdout = subprocess.PIPE,           #正确的指令存放位置
        stderr = subprocess.PIPE            # 错误的指令存放位置  
    )
    print(sub_obj.stdout.read().decode("gbk")) # read 拿到的是字节,需要解码(需要解码的字节是系统默认的)
    import struct
    
    a = 10
    
    byt = struct.pack("i",a)  # 将int类型的a打包成4个字节长度的二进制
    
    a1 = struct.unpack("i",byt)  # 将byt解包成一个int类型,返回的是一个元组

    三.两种粘包现象(TCP)

      1.连续(发送数据间隔短)两个小的数据流会被优化算法给组合到一起并发送,造成粘包

    模拟粘包现象服务端

    import socket
    
    server = socket.socket()
    ip_port = ("127.0.0.1",8888)
    server.bind(ip_port)
    server.listen()
    conn,addr = server.accept()
    
    from_client_msg1 = conn.recv(1024)
    print(from_client_msg1)
    from_client_msg2 = conn.recv(1024)
    print(from_client_msg2)

    模拟粘包现象客户端

    import socket
    
    client = socket.socket()
    client.connect(("127.0.0.1",8888))
    
    to_send1 = client.send(b"123")
    to_send2 = client.send(b"123")

      2.一个大的数据流过大,超过revc的值,那么会一次接收不完,暂时存放在缓冲区,下次再接收的时候就会拿到一六的数据,造成粘包

    模拟粘包现象服务端

    import socket
    import subprocess
    
    server = socket.socket()
    ip_port = ("127.0.0.1",8888)
    server.bind(ip_port)
    server.listen()
    conn,addr = server.accept()
    while 1:
        from_client_cmd = conn.recv(1024).decode("utf-8")   # 一次只能接收1024b 剩下的存在缓冲区 第二次再接收会粘包
    
        sub_obj = subprocess.Popen(
            from_client_cmd,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        to_client_res = sub_obj.stdout.read()
        print(len(to_client_res))
        conn.send(to_client_res)

    模拟粘包现象客户端

    import socket
    
    client = socket.socket()
    ip_port = ("127.0.0.1",8888)
    client.connect(ip_port)
    
    while 1:
        cmd = input("请输入cmd指令:").encode("utf-8")         # 输入ipconfig -all 
        client.send(cmd)
    
        server_cmd_res = client.recv(1024).decode("gbk")
        print(server_cmd_res)

    四.产生粘包的原因及解决方案

      1.产生粘包的原因:接收方不知道消息之间的界限,不知道一次性提取多少数据造成的

      2.解决粘包现象的方案:自定义一个长度报头

    解决粘包现象服务端

    import socket
    import subprocess
    import struct
    
    server = socket.socket()
    ip_port = ("127.0.0.1",8888)
    server.bind(ip_port)
    server.listen()
    
    conn,addr = server.accept()
    
    while 1:
        from_client_cmd = conn.recv(1024).decode("utf-8")
    
        sub_obj = subprocess.Popen(
            from_client_cmd,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        # print(sub_obj.stdout.read())
        sub_res = sub_obj.stdout.read()
        cmd_len = len(sub_res)
        cmd_len_byt = struct.pack("i",cmd_len)
        conn.send(cmd_len_byt + sub_res)  

    解决粘包现象客户端

    import socket
    import struct
    
    client = socket.socket()
    client.connect(("127.0.0.1",8888))
    
    while 1:
        cmd = input("请输入cmd指令:").encode("utf-8")
        client.send(cmd)
    
        cmd_len_byt = client.recv(4)
        cmd_len = struct.unpack("i",cmd_len_byt)[0]
    
        cmd_msg = client.recv(cmd_len).decode("gbk")
        print(cmd_msg)
  • 相关阅读:
    Oracle11g新建用户及用户表空间
    PLSQL连接oracle12c
    Zabbix微信报警脚本及写触发记录
    使用document.select(Jquery Css selector) selector:看jsoup文档来敲案例学习 selector选择器
    仙女打卡day1
    XML的解析(读取),附带源码与运行效果图 (day01)
    [Luogu] P7077 函数调用
    [Luogu] P5815 [CQOI2010]扑克牌
    [Luogu] CF364D Ghd
    [Luogu] P4823 [TJOI2013]拯救小矮人
  • 原文地址:https://www.cnblogs.com/q767498226/p/10225769.html
Copyright © 2011-2022 走看看