没有接收时检测端点关闭?

时间:2013-12-13 01:11:43

标签: c# sockets tcp

这是一个TCP / IP问题,因为我不得不做这个协议已经有一段时间了。首先是一些背景信息。我们在不同的端口上发送和接收。我们在我们这边使用.NET,另一边是AS 400机器。

我们遇到的问题与服务器何时关闭其接收端口以及我们仍然成功从客户端代码发送到其端口有关。服务器端(AS 400机器)处于FIN_WAIT_2状态,因此永远不会从我们的客户端获得最终关闭(我们不断调用send,并且仅在写入异常时重新连接)。我理解,仅仅因为套接字上的发送成功,不保证传递到端点。是通过在套接字上执行接收并返回0字节来检测套接字的唯一方法吗?我们目前没有在这个端口上进行任何接收,看起来我们只是在结束后才会在写入时获得套接字异常实际等待最终结束。

1 个答案:

答案 0 :(得分:3)

听起来发生的事情是AS / 400正在进行正确的TCP / IP关闭:即,它的发送流(您的接收流)已关闭,然后它将从其接收流(您的发送流)中读取)直到你关闭它。这是一种老式的多步闭合握手,几乎没有人每个人都会这样做,但它仍然在书上作为“适当和推荐”的方式来做到这一点。 :)

特别是,FIN_WAIT_2表示AS / 400已发送FIN(关闭)并已收到该FIN的ACK。 (ACK由OS发送,因此即使您没有阅读,它们也至少会得到ACK)。然后等待你的FIN,永远不会发送。

我的纯粹主义者想说你应该总是进行异步读取,并在获得EOF(0长度读取)时关闭套接字。

或者,如果您使用Shutdown致电SocketShutdown.Receive可能会工作,但我的直觉是它不会。如果AS / 400正在发送实际数据,那么它将返回一个RST,但如果它只是发送一个FIN,那么即使你关闭接收流,我认为它只会得到一个ACK,所以我不认为 Shutdown(SocketShutdown.Receive)可行。