zoukankan      html  css  js  c++  java
  • 解决粘包问题

    数据粘包,是由于tcp其独特的流式传输导致的。

    产生的场景有;

    第一种:发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包)

    from socket import *
    ip_port=('127.0.0.1',8080)
    
    tcp_socket_server=socket(AF_INET,SOCK_STREAM)
    tcp_socket_server.bind(ip_port)
    tcp_socket_server.listen(5)
    
    
    conn,addr=tcp_socket_server.accept()
    
    
    data1=conn.recv(10)
    data2=conn.recv(10)
    
    print('----->',data1.decode('utf-8'))
    print('----->',data2.decode('utf-8'))
    
    conn.close()
    View Code
    View Code client

    第二种:接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包) 

    from socket import *
    ip_port=('127.0.0.1',8080)
    
    tcp_socket_server=socket(AF_INET,SOCK_STREAM)
    tcp_socket_server.bind(ip_port)
    tcp_socket_server.listen(5)
    
    
    conn,addr=tcp_socket_server.accept()
    
    
    data1=conn.recv(2) #一次没有收完整
    data2=conn.recv(10)#下次收的时候,会先取旧的数据,然后取新的
    
    print('----->',data1.decode('utf-8'))
    print('----->',data2.decode('utf-8'))
    
    conn.close()
    View Code
    import socket
    BUFSIZE=1024
    ip_port=('127.0.0.1',8080)
    
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    res=s.connect_ex(ip_port)
    
    
    s.send('hello feng'.encode('utf-8'))
    View Code

    解决

    一是约定数据包长度,即发送端和接收端约定一样的发送和接收的数据包长度,这样可以清晰的获取到我们需要的数据;
    二是使用分隔符,比如smtp协议就是在发送时,使用 为分隔符,但如果我们要发送的数据中也有 呢,就容易搞混淆,所以不是特别推荐;
    三是在每个数据包的开头利用2个或者4个字节填充整个数据包的长度,这样接收端可以先接收2个或者4个字节,就可以准确的知道真正的数据包是多长,从而正确获取需要的数据;

  • 相关阅读:
    Day 19
    Day 18
    Day17
    Day 16
    正则表达式(仅可输入中文英文数字以及英文逗号)
    Linux安装Nginx 并搭建图片服务器
    Mysql创建用户表并利用存储过程添加100万条随机用户数据
    Dubbo(高性能、轻量级的开源Java RPC框架) & RPC(远程过程调用)
    Redis
    OSI (开放系统互联(Open System Interconnection))
  • 原文地址:https://www.cnblogs.com/topass123/p/12682344.html
Copyright © 2011-2022 走看看