代码之家  ›  专栏  ›  技术社区  ›  Tim

NetworkStream获取系统。IO。IOException:无法将数据写入传输连接

  •  6
  • Tim  · 技术社区  · 6 年前

    我正在使用NetworkStream保持一个开放的TCP/IP连接,消息可以通过该连接发送。我接收消息,对其进行处理,然后返回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 回复  |  直到 6 年前
        1
  •  8
  •   TheGeneral    6 年前

    你认为这是一个普遍的问题是对的,所以你必须更加防御性。

    一些需要考虑的事情

    1. 当应用程序以正确的方式关闭套接字时,它会发送一条包含0字节的消息。
    2. 在某些情况下,您可能会 SocketException 表明出了问题。
    3. 在第三种情况下,在双方之间没有任何通信的情况下,远程方不再连接(例如通过拔下网络电缆)。

      • 如果发生这种情况,您必须将数据写入套接字,以便检测到您无法再访问远程方。这就是为什么发明了保持生命的机制——它们经常检查自己是否还能与对方进行通信。

    笔记 :所有这些都不能解释 问题(如果我读对了)


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

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

    IO异常

    • 写入网络时出错。
    • 访问套接字时出错。有关更多信息,请参阅备注部分。

    备注:

    如果您收到 套接字异常 ,使用 SocketException.ErrorCode 属性以获取特定错误 代码,以及 请参阅Windows Sockets版本2 API错误代码 MSDN中有关错误详细描述的文档


    所以在我看来,正如前面提到的,你需要更具防御性。

    1. 检查0字节。

    2. 检查错误。

      • 如果您遇到错误,请确保您正在检查错误代码

    在这两种情况下,重新启动连接、记录故障并假设连接已关闭(或异常关闭)可能是一种良好的做法(也是有意义的)


    其他资源

    Detect closed network connection

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