c - 非阻塞 tcp 套接字如何通知应用程序发送失败的数据包。

标签 c linux sockets tcp

我正在为 Linux 系统开发一个非阻塞 C tcp 套接字。我读到,在非阻塞模式下,如果没有错误,“发送”命令将立即返回“发送的字节”。我猜测返回的这个值实际上并不意味着这些数据已传递到目的地,而是数据已传递到内核内存以供其进一步处理和发送。

如果是这种情况,假设网络连接出现一些问题并且内核在一段时间内重试几次后才决定放弃,那么我的应用程序如何知道内核确实将哪个数据包发送到另一端几分钟后?

我问这个问题是因为我希望我的应用程序稍后再次重新发送这些失败的数据包。

最佳答案

If that is the case, how would my application know which packet has really been sent out by kernel to the other end, assuming that the network connection had some problems and kernel decides to give up only after several retries in a span of a few minutes later?

您的应用程序不会知道,除非它能够重新联系接收应用程序并询问接收应用程序之前收到了哪些数据。

请记住,即使使用阻塞 I/O,您的应用程序也不会阻塞,直到远程应用程序接收到数据为止——它只会阻塞,直到内核的传出数据缓冲区中有一些空间来保存您的字节。要求 TCP 堆栈发送()。因此,即使使用阻塞 I/O,您也会面临同样的问题。

另请记住,传递给 send() 的字节数组不保证与 TCP 堆栈发出的 TCP 数据包一一对应。 TCP 堆栈可以随意将字节打包到 TCP 数据包中(例如,来自多个 send() 调用的数据可能最终出现在单个 TCP 数据包中,或者来自单个 send() 调用的数据可能最终出现在多个 TCP 数据包中。 TCP 数据包或您能想到的任何其他组合)。根据网络条件,TCP 堆栈可以并且确实以各种不同的方式打包内容,它们唯一的 promise 是字节将以 FIFO 顺序接收(如果它们完全被接收的话)。

无论如何,你的问题的答案是:你无法知道,除非你稍后询问接收程序它得到了什么(或没有得到)。

关于c - 非阻塞 tcp 套接字如何通知应用程序发送失败的数据包。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24027606/

相关文章:

c - 将数组写入二进制文件?

c - 在 Visual Studio 中是否有任何选项可以在 C99 和 C11 C 标准之间切换?

python - 虚拟机设置和同步项目依赖

c++ - 检测Linux中system()函数返回值的含义

java - 健壮的 Java 套接字编程

C编程: Pointer to a row of a 2D array?

c - 使用/将Linux shell命令 "echo 1=200 >/dev/mydevice"转换为c程序

linux - 在 AWK 中使用管道

c# - 什么条件导致 NetworkStream.Write 阻塞?

python - Errno 111 连接在 Python 套接字编程中被拒绝