查明 TCP 上的消息是否已送达
- 2024-11-04 08:43:00
- admin 原创
- 32
问题描述:
当我通过 tcp 流发送 ()/写入 () 消息时,如何知道这些字节是否已成功传送?
接收方确认通过 tcp 接收字节,因此发送方 tcp 堆栈应该知道。
但是当我 send() 一些字节时,send() 会立即返回,即使数据包无法(暂时)传送,我也在 linux 2.6.30 上使用 netcat 上的 strace 进行了测试,在发送一些字节之前拔出网线。
我正在开发一个应用程序,其中了解消息是否已送达非常重要,但实现 tcp 功能(“确认消息#123”)感觉很尴尬,一定有更好的方法。
解决方案 1:
发送 TCP 确实知道数据何时被另一端确认,但是它这样做的唯一原因是它知道何时可以丢弃数据(因为现在其他人负责将其传送到另一端的应用程序)。
它通常不会向发送应用程序提供此信息,因为(尽管表面上如此)它实际上对发送应用程序来说意义不大。确认并不意味着接收应用程序已收到数据并对其进行了合理的处理 - 它只意味着发送 TCP 不再需要担心它。数据可能仍在传输中 - 例如在中间代理服务器中,或在接收 TCP 堆栈中。
“数据成功接收”实际上是一个应用程序级概念 - 它的含义因应用程序而异(例如,对于许多应用程序来说,只有在数据同步到接收端的磁盘后,才认为数据“已接收”才有意义)。所以这意味着你必须自己实现它,因为作为应用程序开发人员,你实际上是唯一一个知道如何为你的应用程序合理地做到这一点的人。
解决方案 2:
让接收方发回确认是最好的方法,即使“感觉很别扭”。请记住,IP 可能会将您的数据拆分为多个数据包并重新组装,如果途中的各个路由器具有不同的 MTU,则此操作可能在传输过程中多次执行,因此您对“数据包”的概念和 TCP 的概念可能不一致。
更好的方法是发送你的“数据包”,无论它是一个字符串,一个序列化对象,还是二进制数据,并让接收方进行任何需要的检查以确保它在那里,然后发回确认。
解决方案 3:
TCP 协议会尽力确保数据能够到达。如果出现网络问题,它会多次重新传输数据。这意味着您发送的任何数据都会被缓冲,无法及时确保数据已到达(如果网络中断,2 分钟后将出现超时)。
如果需要快速反馈,请使用 UDP 协议。它不使用任何 TCP 开销,但您必须自己处理所有问题。
解决方案 4:
即使它到达了 TCP 层,也不能保证它不会停留在应用程序的缓冲区中,然后应用程序在处理它之前就崩溃了。使用确认,这就是其他所有东西所做的(例如 SMTP)
解决方案 5:
除非特别提供通知,否则应用层无法控制较低层(例如传输层)的通知 - 这是设计使然。如果您想知道 TCP 在每个数据包级别上正在做什么,您需要找出 TCP 运行的层;这意味着处理 TCP 标头和 ACK 数据。
但是,您最终用来承载有效负载的任何协议都可用于通过该有效负载来回传递消息。因此,如果您觉得使用 TCP 标头的位来执行此操作很不方便,只需在您的应用程序中进行设置即可。例如:
A: Send 450 Bytes
B: Recv 450 Bytes
B: Send 'B received 450 Bytes'
A: Recv 'B received 450 Bytes'
A: Continue
解决方案 6:
这听起来像是SCTP值得一看;我认为它应该支持你想要的。另一种选择似乎是切换到 UDP,如果你无论如何都要切换协议……
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件