NetworkStream gets System.IO.IOException: 无法将数据写入传输连接

NetworkStream gets System.IO.IOException: Unable to write data to the transport connection

我正在使用 NetworkStream 保持打开的 TCP/IP 连接,消息可以通过该连接发送。我收到一条消息,处理它,然后 return 一个 ACK​​。我正在使用一个偶尔会收到消息的站点,但是当我发送 ACK 时,我收到了 IOException。有时这只会持续一两条消息(我可以收到下一条消息),而其他时候它会一直持续到服务停止并重新启动。

下面是我的 NetworkStream 的代码,没有任何处理:

using (NetworkStream stream = client.GetStream())
{
   stream.ReadTimeout = ReadTimeout;
...
   if (stream.CanRead && stream.DataAvailable)
   bytesRead = stream.Read(receivedBytes, 0, BufferSize);
...
   stream.Write(ack, 0, ack.Length);
}

请注意,代码在读取新消息和发送 ACK 之间循环。

当我调用stream.Write时,有时会出现以下异常:

System.IO.IOException: Unable to write data to the transport connection: An established connection was aborted by the software in your host machine. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at Framework.Communication.Model.Server.AcceptMessage(IAsyncResult ar)

我查看了这条消息并找到了几个 sources 用于几种不同的通信方法。听起来这是一个非常通用的异常,并不能真正说明发生了什么。

有谁知道是什么原因导致的,或者我可以从哪里开始寻找缩小解决方案的范围?

你认为这是一个普遍的问题是正确的,所以你将不得不更加防御。

需要考虑的事项

  1. 当应用程序以正确的方式关闭套接字时,它会发送一条包含 0 字节的消息。
  2. 在某些情况下,您可能会收到 SocketException 指示出错的消息。
  3. 第三种情况,对方不再连接(比如拔掉网线),双方没有任何联系

    • 如果发生这种情况,您将不得不向套接字写入数据,以检测您是否无法再联系到对方。这就是 keep-alive 机制被发明的原因 - 他们经常检查他们是否仍然可以与另一方通信。

Note : None of this explains the intermittent nature of part of the question (if i'm reading it correctly)


所以让我们看看文档是怎么说的

NetworkStream.Write Method (Byte[], Int32, Int32)

IOException

  • There was a failure while writing to the network.
  • An error occurred when accessing the socket. See the Remarks section for more information.

Remarks

If you receive a SocketException, use the SocketException.ErrorCode property to obtain the specific error code, and refer to the Windows Sockets version 2 API error code documentation in MSDN for a detailed description of the error.


所以在我看来,如前所述,您需要更具防御性。

  1. 检查 0 字节。

  2. 检查错误。

    • 我收到一个错误,请确保您正在检查错误代码

在任何一种情况下,再次重新启动连接、记录失败并假定连接已关闭(或异常关闭)可能是好的做法(并且有意义)


其他资源

Detect closed network connection

**** Detection of Half-Open (Dropped) Connections **** 斯蒂芬·克利里