TCP 传输协议中如何解决丢包问题

2019-08-07 12:05:15 +08:00
 raysync111

TCP 在不可靠的网络上实现可靠的传输,必然会有丢包。TCP 是一个“流”协议,一个详细的包将会被 TCP 拆分为好几个包上传,也是将会把小的封裝成大的上传,这就是说 TCP 粘包和拆包难题。

但是许多人有不同的理解。TCP 协议本身确保传输的数据不会丢失完整性。如果在传输过程中发现数据丢失或数据包丢失,最大的可能性是在发送或接收程序的过程中出现问题。

例如,服务器向客户端发送大量数据,并且发送频率非常高,因此发送链接中很可能会出现错误( 1、程序处理逻辑错误; 2、多线程同步问题; 3、缓冲区溢出等)如果发送失败得不到处理,那么客户端收到得数据将少于理论数据,这将导致数据丢失与数据包丢失。这种现象,其实本质上来说不是丢包,也不是丢数据,只是因为程序处理有错误,导致有些数据没有成功地被 socket 发送出去。

关于 send 函数的问题: 首先必须明确 send 函数做了什么。 他是将数据传递给本地 TCP 层,还是将数据传递给应用层,确认接收方 TCP 层后再返回。在后者的情况下,你说的没错,其实不然。 那是由于 nagle 算法不能使用了,即该算法将 send 函数接收的小数据汇总成大数据包发送。

即使 send 函数能进行数据发送,对方也不一定被接受。 TCP 协议只是在传输层履行义务,send 函数只是应用层起到向 TCP 层传递数据的作用,除此之外与 TCP 层没有任何关系。

常见的解决方案包括拆包、添加包头和发送组合包。如果服务器或客户端断开连接,一般会使用心跳测试。 心跳测试:每隔一段时间向服务器发送数据包。为了节省资源,通常会发送空数据包。如果发送失败表明套接字已断开,此时需要根据特定条件释放资源并重新连接。

TCP 传输可以保证数据交换的可靠性,这意味着一台主机将数据正确地传输到目标计算机,目标计算机的协议栈有一定的限制,如果不及时处理在目标计算机上接收到的数据,堆栈就会溢出。 这种溢出不是由 TCP 协议本身引起的,而是由系统的 IP 协议栈的缓冲区溢出引起的。

1158 次点击
所在节点    推广
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/589783

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX