【发布时间】:2017-04-12 09:50:39
【问题描述】:
我目前正在假设使用 System.Net.Sockets.Socket.Send 发送 TCP 数据时,如果连接断开,我保证会收到异常。是否可以在操作系统层断开连接而不会在顶部的 C# 应用程序中收到通知/异常?
我不认为 .net 中存在这种情况,但我将如何向持怀疑态度的人展示这一点。
【问题讨论】:
-
使用TCP,没有“数据包”之类的东西。 TCP 是一种面向流的协议,这意味着数据只是一个大字节流。如果您在流结束之前接收数据(接收操作以 0 字节完成),您可以 100% 肯定发送给您的所有数据实际上已被接收。当然,如果你强行终止连接,或者如果你保持连接打开,并且想知道你是否收到了到目前为止发送的所有内容,不......没有办法确定你已经收到了。
-
如果您是发送者,那么确定远程端点是否已收到您的数据的唯一方法就是询问它。当然,一种方法是让您的应用程序级协议要求远程端点保持其连接打开,直到它接收到您发送的所有数据。在这种情况下,从远程端点接收来自的流结束通知发送者他们已经收到了所有内容。但显然这适用于一个方向的数据。如果没有额外的协商,两个端点不可能知道每个端点都收到了对方的数据。
-
当我说数据包时,我指的是一个包含 TCP 段的 IP 数据报。
-
“我指的是一个包含 TCP 段的 IP 数据报”——我不知道怎么做。套接字本身并不发送这些,当然底层网络层将客户端传输转换为它们。但是无所谓。那些总是被丢弃。 TCP 的重点是客户端代码永远不会看到这一点。该协议确保丢弃的 IP 数据报被重新发送,并由客户端以正确的顺序接收。
-
“.net 无法从操作系统层断开连接怎么办?” - 这将是一个错误,而且非常不可能。没关系,有太多基于
Socket的程序(我猜有数以万计的“严肃”程序,可能至少有100 个),而Socket本身就是一个非常Winsock 上的薄层,它本身已经使用了二十多年。您真正需要担心的是您自己的代码。它包含错误的可能性大约是Socket类的一百万倍。
标签: c# networking