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)
  • 相关阅读:
    toj 2975 Encription
    poj 1797 Heavy Transportation
    toj 2971 Rotating Numbers
    zoj 2281 Way to Freedom
    toj 2483 Nasty Hacks
    toj 2972 MOVING DHAKA
    toj 2696 Collecting Beepers
    toj 2970 Hackle Number
    toj 2485 Card Tric
    js页面定位,相关几个属性
  • 原文地址:https://www.cnblogs.com/q767498226/p/10225769.html
Copyright © 2011-2022 走看看