如果数据包传递永久失败,TCP / IP如何报告错误?我看到的所有Socket.write()API都只是将字节传递给底层TCP / IP输出缓冲区并异步传输数据。如果数据包传递永久失败(即目标主机不再可访问),TCP / IP应该如何通知开发人员?
任何要求发件人等待远程端确认的协议都会收到错误消息。但是对于发送方不必从目标读取任何字节的协议会发生什么? TCP / IP是否只是默默地失败?也许Socket.close()会返回错误? TCP / IP规范是否说明了这一点?
答案 0 :(得分:5)
TCP / IP是一种可靠的字节流协议。您的所有字节都将到达接收方,否则您将收到错误指示。
错误指示将以封闭套接字的形式出现。无论通信模式是什么(谁发送),如果无法传递字节,套接字将关闭。
所以问题是,你如何看待套接字关闭?如果你从来没有读过,你最终会在尝试写入已关闭的套接字时遇到错误(我认为使用ECONNRESET错误)。
如果您需要睡眠或等待另一个文件句柄的输入,您可能希望在select()调用中等待,其中您将套接字包含在您正在等待的源列表中(即使你永远不会期待收到任何东西)。如果select()指示套接字已准备好进行读取调用,则可能会返回-1(我认为使用ECONNRESET)。 EOF表示有序关闭(另一方执行关闭()或关闭()。
如何将此错误与干净关闭(例如其他程序退出)区分开来? errno值可能足以将错误与有序关闭区分开来。
如果您想要明确指出问题,您可能需要在套接字层之上构建某种应用程序级协议。例如,接收方发送给发送方的短“ack”消息。然后违反更高级别的应用程序协议(发件人没有看到确认)将确认它是一个错误关闭与干净关闭。
答案 1 :(得分:4)
套接字API无法通过对等方确认已接收到多少字节。成功shutdown
或close
的存在也无法保证。
TCP / IP规范没有提及应用程序接口(几乎总是套接字API)。
SCTP是TCP的替代方案,它试图解决这些缺点等问题。
答案 2 :(得分:0)
在C中,如果您使用send()写入失败的套接字,您将获得已发送的字节数。如果这与您要发送的字节数不匹配,那么您就遇到了问题。但是,当你写入一个失败的套接字时,你会得到SIGPIPE。在开始套接字处理之前,您需要有一个信号处理程序,当您收到SIGPIPE时会提醒您。
如果你正在读取一个套接字,你真的应该用一个警报包装它,这样你就可以超时了。像“alarm(timeout_val); recv(); alarm(0)”。检查recv的返回码,如果为0,则表示连接已关闭。否定返回结果表示读取失败,您需要检查错误。
答案 3 :(得分:0)
TCP建立在IP协议的基础之上,IP协议是互联网的核心,提供了驱动路由的大部分互操作性,这决定了如何将数据包从源路由到目的地。 IP协议规定,如果数据包无法到达发送方,则应通过Internet控制消息协议(ICMP)将错误消息发送回发送方。其中一些原因包括生存时间(TTL)字段递减为零,通常意味着数据包卡在路由循环中,或者由于交换机争用而导致数据包丢失导致缓冲区溢出。正如其他人所说,Socket API的责任是用于在IP层将这些错误转发到与TCP层的网络交互的应用程序。