• Python—TCP的黏包问题以及UDP的分片问题


    TCP协议与UDP协议

    1. TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 即面向流的通信是无消息保护边界的。

    2. UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。

    3. tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,而udp是基于数据报的,即便是你输入的是空内容(直接回车),那也不是空消息,udp协议会帮你封装上消息头。

    TCP与UDP的不同接包处理方式

    1.TCP的发包问题

    问:tcp 发送两次数据,第一次发送100字节 ,第二次发送200字节, 接包方一次recv( 1000 )会接收到多少?收到是 100,还是200,还是300?

    答:tcp 是流协议,所以recv( 1000 ),会收到300。tcp自己处理好了重传,保证数据包的完整性。

    2.UDP的发包问题

    问:udp 发送两次数据,第一次发送100字节 ,第二次发送200字节, 接包方一次recvfrom( 1000 )会接收到多少?收到是 100,还是200,还是300?

    答:udp 是数据报文协议,是以数据包方式,所以每次可以接收100,200,在理想情况下,第一次是无论recvfrom多少都是接收到100。当然,可能由于网络原因,第二个包先到的话,有可能是200了。对可能会由于网络原因乱序,所以可能先收到200,所以自定义的udp协议包头里都要加上一个序列号,标识发送与收包对应。

    3.有分片的情况下如下处理

    问:如果MTU是1500,Client发送一个8000字节大小的UDP包,那么Server端阻塞模式下接包,在不丢包的情况下,recvfrom(9000)是收到1500,还是8000。如果某个IP分片丢失了,recvfrom(9000),又返回什么呢?

    答:根据UDP通信的有界性,在buf足够大的情况下,接收到的一定是一个完整的数据包,UDP数据在下层的分片和组片问题由IP层来处理,提交到UDP传输层一定是一个完整的UDP包,那么recvfrom(9000)将返回8000。如果某个IP分片丢失,udp里有个CRC检验,如果包不完整就会丢弃,也不会通知是否接收成功,所以UDP是不可靠的传输协议,那么recvfrom(9000)将阻塞。

    问:如果MTU是1500,使用UDP发送 2000,那么recvfrom(2000)是收到1500,还是2000?

    答: 还是接收2000,数据分片由ip层处理了,放到udp还是一个完整的包。接收到的包是由路由路径上最少的MTU来分片,注意转到UDP已经在是组装好的(组装出错的包会经crc校验出错而丢弃),是一个完整的数据包。

    http://www.360doc.com/content/20/0226/20/68763366_895040549.shtml

    http://www.360doc.com/content/17/0707/14/33093582_669586885.shtml

    http://www.360doc.com/content/17/0724/11/33093582_673722332.shtml

    https://blog.csdn.net/caoshangpa/article/details/51530685

    https://www.cnblogs.com/x_wukong/p/5995525.html

    https://www.cnblogs.com/zsychanpin/p/6795524.html

    https://www.cnblogs.com/xiao-apple36/p/9276777.html

    https://www.cnblogs.com/weihengblog/p/8618372.html

  • 相关阅读:
    spring注解方式AOP
    struts2 值栈的理解
    JAVA自定义注解
    JS学习随笔。
    使用Jsoup解析html网页
    Struts迭代器(iterator)遍历List常用的4种例子
    Maven 结合 Spring profile对不同的部署环境打包部署
    打印插件LODOP使用介绍
    Linux下查看CPU信息、机器型号等硬件信息
    验证码的生成和验证
  • 原文地址:https://www.cnblogs.com/liuhaidon/p/12368809.html
Copyright © 2020-2023  润新知