IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> TCP协议.之发送数据,粘包,拆包问题(二) -> 正文阅读

[网络协议]TCP协议.之发送数据,粘包,拆包问题(二)

Tcp协议发送数据,粘包,拆包问题,这句话本身是错误的,tcp是协议,发送接收数据时并不会粘包,tcp,ip,只负责传输数据
粘包是应用层解析数据时,包1和包2粘连在一起,解析数据时,出现错误的,网络中,很多博主,就没搞清楚。

send,发送频率太快,发送包的时候,有可能发送1400字节,或100个字节,按流的方式发送,应用层很快频率,非阻塞去recv数据时,不一定能读到1400个字节,可能只有1000个,下次再去读取时,读到应用层发送的第一包里的后400个字节开头的数据包,出现粘包,解析数据头是出错,其实tcp传输数据时,没有包的概念,和uart串口一样,只有流的概念,tcp协议讲的很清晰,tcp是面向流的,一个一个字节流,
tcp传输时,只按流的方式发送,没有一包一包的概念,假如发送数据很大,tcp协议,自动分成多包一个一个字节进行发送,接收端接收到数据,会自动按包号,进行组合假如分成1,2,3,4,5包,接收端接收到1,2,4,5,底层协议自动组合,错误将自动重传,所以,tcp是可靠的传输。

这个包和应用层send发包不是一个概念,udp才是面向报文的,应用层按包发送接收,发送1400字节的包,udp只要网络正常,基本一定能收到1400个字节的包,tcp不一定能recv能接收到1400个字节,所以如果用结构,去解析包头,数据段的数据,这时候,有可能就回错误,包头校验不对,如下一段代码,用结构类型去解析接收buf的数据,注意,我这里qt的read接收的,linux是recv。

	PT_udpSocketDataPkt _tDataPkt1 = (PT_udpSocketDataPkt)this->databufer2;
	memset(_tDataPkt1, 0, sizeof(T_udpSocketDataPkt));

	int rcvlen = ClientTcpSocket->read((char*)_tDataPkt1, UDP_MAX_LEN);//最多读1400个
	if(rcvlen <= 0)
	{
	    QMessageBox::information(this, CCODE("提示"), CCODE("接收服务端数据失败!"));
	}
	else if ( ( (rcvlen >= UDP_MIN_LEN) && (rcvlen <= UDP_MAX_LEN) )  \
	&& (_tDataPkt1->DataHead.u32Sync == PKT_SYNC) && (_tDataPkt1->DataHead.u8Cmd = CMD_SNAP_PIC_CMD_ACK))
	{
		if (_tDataPkt1->DataHead.u16TotalPktNum != _tDataPkt1->DataHead.u16CurrentPktSn)//接收到一包数据
		{
		}
	}
			

如果服务端发数据够快,客服端读取数据时,就可能解析不对,也是被udp干扰了,写udp时,就是按包发送,接收,去解析的,没问题。
放到tcp就有可能有问题。
csdn很多博主,在解决粘包问题时,其中解决方法,是这样建议的,没有考虑这个问题,什么极端情况都可能出现的。

tcp应用层解析数据时,发送大量数据,很有可能会出现这样情况,上面的方法其实也可以在某系业务时可用,如发送频率较慢,几ms发送数据,接收端慢一点,能及时处理读取全部数据,并且回复发送端,收到已处理消息,接收端再发送,就可以这样,但是发送数据很慢,传输一个几mb的文件,很慢,这样用udp协议也可以了,就没必要用tcp了,tcp就是可靠。

如果是传输大文件时,只需发送方告诉接收方,文件的大小,接收按流的方式读取到buf里,recv多少个字节,就放到buf里,直到收完大小为止,后者,很多人建议的。
如果事先不知道文件大小,也可以这样做,在数据里,加结束标志如\\\,读到包结束标志后,表示完整包发送完毕。

需要处理大量数据时,最好还是按流的方式处理数据,放到buf里,如果数据是报文,消息,可以加标志位,应用层根据结束标志位,在流buf里,寻找一个完整的包,如果是连续的文件,接收多少个字节,就按多少个字节拼接到buf里。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:39:57  更:2022-04-27 11:41:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:25:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码