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个字节,就可以准确的知道真正的数据包是多长,从而正确获取需要的数据;

  • 相关阅读:
    MQTT服务器搭建--Mosquitto用户名密码配置
    linux下c语言获取当前时间
    Linux下用C获取当前时间
    iptraf:一个实用的TCP/UDP网络监控工具
    CentOS配制FTP服务器,并且能用root权限登录
    centos6.4搭建ftp服务器
    两台Linux主机互传文件可以使用SCP命令来实现
    Linux 技巧:让进程在后台可靠运行的几种方法
    Linux 下 c 语言 聊天软件
    RobotFrameWork(五)控制流之if语句——Run Keyword If
  • 原文地址:https://www.cnblogs.com/topass123/p/12682344.html
Copyright © 2011-2022 走看看