Python—TCP的黏包问题以及UDP的分片问题
TCP协议与UDP协议
TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 即面向流的通信是无消息保护边界的。
UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。
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
Python—TCP的黏包问题以及UDP的分片问题的更多相关文章
- tcp黏包问题与udp为什么不黏包
1.先说下subprocess模块的用法,为了举个黏包的例子 # 通过一个例子 来认识网络编程中的一个重要的概念 # 所有的客户端执行server端下发的指令,执行完毕后,客户端将执行结果给返回给服务 ...
- python基础(30):黏包、socket的其他方法
1. 黏包 1.1 黏包现象 让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd) 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接 ...
- tcp传输黏包
tcp传输黏包 tcpip协议使用"流式"(套接字)进行数据的传输,就是说它保证数据的可达以及数据抵达的顺序,但并不保证数据是否在你接收的时候就到达,特别是为了提高效率,充分利用带 ...
- Python Socket通信黏包问题分析及解决方法
参考:http://www.cnblogs.com/Eva-J/articles/8244551.html#_label5 1.黏包的表现(以客户端远程操作服务端命令为例) 注:只有在TCP协议通信的 ...
- 黏包现象之udp
老师的博客:http://www.cnblogs.com/Eva-J/articles/8244551.html server端 import socket import subprocess ser ...
- python之路----黏包的解决方案
黏包的解决方案 远程执行命令 # server 下发命令 给client import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) ...
- python 缓冲区 subprocess 黏包 黏包解决方案
一.缓冲区 二.两种黏包现象 两种黏包现象: 1 连续的小包可能会被优化算法给组合到一起进行发送 黏包现象1客户端 import socket BUFSIZE = 1024 ip_prort = (' ...
- python tcp 实时抓包
问题:之前我们系统上线后,因为是旧的系统,没有加统计的功能,比如用户喜欢那个页面,是哪些用户再访问,接口的负载能力等等. 解决办法:1,现有代码更改,添加功能.现有代码侵入太多,工作量比较大 2,想到 ...
- python socket编程和黏包问题
一.基于TCP的socket tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端,有顺序,不重复,可靠.不会被加上数据边界. server端 import socket sk = so ...
随机推荐
- Nginx配置不同端口号映射二级域名
upstream xx{ #ip_hash; server 127.0.0.1:1008; } server { listen 80; server_name xx.xxx.com; location ...
- 51Nod 2026 Gcd and Lcm
题目传送门 分析: 开始玩一个小小的trick 我们发现\(f(n)=\sum_{d|n}\mu(d)\cdot d\)是一个积性函数 所以: \(~~~~f(n)=\prod f(p_i^{a_i} ...
- hadoop中两种上传文件方式
记录如何将本地文件上传至HDFS中 前提是已经启动了hadoop成功(nodedate都成功启动) ①先切换到HDFS用户 ②创建一个user件夹 bin/hdfs dfs -mkdir /user ...
- Canny边缘检测算法(基于OpenCV的Java实现)
目录 Canny边缘检测算法(基于OpenCV的Java实现) 绪论 Canny边缘检测算法的发展历史 Canny边缘检测算法的处理流程 用高斯滤波器平滑图像 彩色RGB图像转换为灰度图像 一维,二维 ...
- 宝塔面板管理阿里云服务器FTP不能用
# 宝塔面板管理阿里云,ftp不能用 解决方法 搜ftp点击设置 然后Ctrl+F搜索ForcePassiveIP 注意2在默认情况下是带#号的,去掉#号,后面的ip地址是阿里云的公网ip 重启,再次 ...
- Dwz/Jquery--使用Ajax提交表单时调用表单设置的校验
案例 今天有一个需求就是点击按钮时,使用ajax方式提交表单,而且不是直接用form表单下的submit按钮提交,表单中用的校验是dwz 自带的校验方式,表单模板如下: <li><d ...
- ros之tf坐标系广播与监听的编程实现
创建功能包-learning_tf $ cd ~/catkin_ws/src $ catkin_create_pkg learning_tf roscpp rospy tf turtlesim 如何创 ...
- CSS颜色表示的几种方式
在CSS中颜色有很多表示方式,今天列出一些常见的颜色表示方式及它们的用法. ①color:blue; 第一种,调用颜色属性,将颜色的英文输入在冒号后,以分号结束. 这种方法直接了当,但是能表示的颜色 ...
- python strip()方法使用
描述 python strip() ,用于去除述字符串头尾指定字符(默认为空格或换行符)或字符序列. 注意:此方法只能去除头尾的空格或是换行符,不能去除中间的. 语法: str.strip([char ...
- SpringBoot Jpa 分页查询最新配置方式
这是已经被废弃的接口 Sort sort = new Sort(Sort.Direction.DESC,"bean类中字段"); //创建时间降序排序 Pageable pagea ...