用C#调用TCP通信的时候,发送的数据存在丢包问题

wPgg1es 发布于 2014/10/14 14:14
阅读 2K+
收藏 2
用C#调用TCP通信的时候,每次发送4096byte,一开始没问题,但是发送一会,接收端接收到的就比4096少了。
加载中
0
翡翠水滴
翡翠水滴

你对 TCP 的理解有问题。tcp 其实是没有包的概念的,它是“流”,底层处理会把所有你提供的数据按顺序发送,但不保证一次发多少,也不保证一次会收到多少,它仅仅保证数据是正确的,并且能送到。

所以如果你想要按包来分割,必须自己在协议里实现:比如先传一个长度,然后从流里读指定长度。

翡翠水滴
翡翠水滴
@wPgg1es 对TCP写重传逻辑是很不合理的做法,别被假象骗了。问题会更严重。
wPgg1es
wPgg1es
回复 @翡翠水滴 : 代码太长,两边加起来600来行,回复里放不开,我加了一个重传的处理,暂时解决了,还是很谢谢你,有问题再请教你。
翡翠水滴
翡翠水滴
@wPgg1es 贴代码吧。描述太累了
wPgg1es
wPgg1es
回复 @翡翠水滴 : 这个肯定写了。
翡翠水滴
翡翠水滴
你写了封包和解包的逻辑吗?
下一页
0
水魚魚
水魚魚
丢包。发送太快就会丢掉。
wPgg1es
wPgg1es
就算,应答-发送这样的方式快速的发送,也会丢吗?
0
水魚魚
水魚魚
读处理太慢,可能会造成底层缓冲区数据溢出,缓冲区满了,后面的数据自然就丢了。
wPgg1es
wPgg1es
奥,我再看看,谢谢!
0
hibegin
hibegin
明确的的告诉你不是掉包。tcp 是流。多半因为在是网络中传输(客户端和服务端不再同一台电脑),tcp是流。如果不能使读取传输过来的流就会导致数据粘在一起的情况的。就会发身粘包的。
wPgg1es
wPgg1es
如果是粘包的话,我再想办法解决吧,谢谢!
0
七液
七液

网络延迟造成的,至于不管如何对TCP进行各种参数设定都是没啥意义的,神马流不流都是概念,就算你知道是流又如何?关心的是如何做到。

首先确定一个前提,TCP不会丢包-至少理论上,如果因为路由器造成的丢包这个不再讨论范围之内(什么你不相信?好吧我只能说你没有遇到过这样的情况,一些路由器的确会丢包,包括TCP协议,只是机率很低,大部分情况下是不会丢包的)

通用解决办法:粘粘包+发送数据

一般数据包发送前,先发送一个固定字节的粘粘包(就是后面的数据有多长)+你要发送的数据,接收的时候会先接收(假设四个字节的粘粘包--最简单的粘粘包就是数据长度,当然还有人加其他的,比如时间戳,数据HASH,数据类型等等,总之原则是固定长度的包)固定长度的粘粘包--如果接不满就循环接收,一直等到完全接受完。recv循环接收,等到粘粘包接收完整了,再从粘粘包里面获取完整的数据长度,再循环接收,这样操作的话不管遇到什么网络延迟造成的断包,粘包等等情况都可以轻松应对,这是王道做法,其他的什么设置关闭TCP的各种参数都是非主流做法,不靠谱,而且根本也无法保证不会出现断包现象。再说许多情况不是发送端造成的,路由器延迟也会造成断包(但是不会丢包。如果怕丢包的话,在粘粘包里面加入HASH,自己再校验一遍)

frankbiao
frankbiao
说的很对
wPgg1es
wPgg1es
非常感谢,明白了!
0
伤神小怪兽
伤神小怪兽
使用 HP-Socket PULL 模型 - 从此不再有粘包烦恼~
伤神小怪兽
伤神小怪兽
回复 @wPgg1es : 任意使用,只需保留版权信息。
wPgg1es
wPgg1es
好的,我试试,顺便问一下,如果使用HP-Socket库的话,在软件许可中要有什么体现?
返回顶部
顶部