C# 发送后服务器立即关闭时从NetworkStream读取数据
我正在使用C# 发送后服务器立即关闭时从NetworkStream读取数据,c#,.net,serialization,io,C#,.net,Serialization,Io,我正在使用二进制读取器从流序列化对象: class MyClass { public void Read(Stream stream) { BinaryReader reader = new Reader(stream); this.someField = reader.ReadSomething(); // IOException } } 一种情况下的问题是,如果我从网络流读取数据,服务器会在发送数据后立即关闭连接。这会导致一个IOE
二进制读取器
从流
序列化对象:
class MyClass
{
public void Read(Stream stream)
{
BinaryReader reader = new Reader(stream);
this.someField = reader.ReadSomething(); // IOException
}
}
一种情况下的问题是,如果我从网络流
读取数据,服务器会在发送数据后立即关闭连接。这会导致一个IOException
(“无法从传输连接读取数据:远程主机强制关闭了一个现有连接。”),甚至在我读取我这边的所有内容之前。如何读取这些数据?它不是在什么地方缓冲的吗
我正在阅读的协议是TLS,如果服务器发送致命警报,就会出现上述情况,我想阅读该警报,之后双方的连接都应该立即关闭
异常消息:
System.IO.IOException
Message=Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Source=System
StackTrace:
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.IO.Stream.ReadByte()
at System.IO.BinaryReader.ReadByte()
at MyClass.Read(Stream stream)
[...]
InnerException: System.Net.Sockets.SocketException
Message=An existing connection was forcibly closed by the remote host
Source=System
ErrorCode=10054
NativeErrorCode=10054
StackTrace:
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
这不应该是个问题。如果服务器确实只发送了所有数据,然后有序地关闭流,那么您应该能够获取它发送的所有数据。如果连接以不太有序的方式终止,或者在其他地方断开,或者在它返回已关闭的事实后继续尝试从中读取,您将看到问题 如果不使用
BinaryReader
,而只是使用流并执行以下操作,会发生什么情况:
// Just log how much data there is...
byte[] buffer = new byte[8 * 1024];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
Console.WriteLine(bytesRead);
}
这不应该仅仅因为套接字正常关闭而引发IOException
。。。它应该退出循环。如果这是可行的,但是您现有的代码抛出了错误,那么您需要检查您在阅读代码时所做的假设(您还没有发布)
这将导致IOException(“连接已关闭…”)
这很可能是由于您关闭了连接,然后试图从中读取数据。远程关闭应该只是导致EOS条件在API中显示的各种方式之一
如果API认为传入的TCP FIN意味着连接已关闭,这将是一个重大错误:它可能是一个关闭,而另一个方向仍然可以操作。您所描述的是单个请求/响应场景中相当常见的模式;那不应该error@MarcGravellJonSkeet:我也这么认为,这不应该是个问题,但是使用嗅探器可以清楚地显示,当BinaryReader抛出异常时,完整的消息到达了我的终端。我将为我的问题添加更多信息。协议是TLS,我在读取致命警报时遇到了这种情况。@rumbdolaf:这就是为什么我建议从等式中删除
BinaryReader
——只需转储流的内容即可,看看能给你多少字节。如果这引发了一个异常,您将知道您确实无法获取数据,并且必须在较低的级别处理正在发生的事情。如果这确实返回了所有数据,那么可能是您如何使用BinaryReader
的问题。我目前正在使用BinaryReaders ReadUInt32等,将尝试“原始”读取,但必须先准备当前代码。好的,我讨厌本地化的异常消息。在我的语言中,他们删除了消息的重要部分:“现有连接被远程主机强制关闭。”因此Stream.Read也有同样的问题,并抛出IOException。我还有什么办法可以得到这些信息吗?正如我所说,嗅探器可以看到所有数据。@rumbdolaf:Stream.read在抛出异常之前读取了多少数据?不,我的立场是def。打开我编辑的完整消息是“无法从传输连接读取数据:远程主机强制关闭了现有连接”。@rumbdolaf这表明发布错误错误消息完全没有意义。这只会浪费每个人的时间。不要那样做。我看不到你在哪里“编辑”了。发布了错误的消息?在您回答之前,完整的异常日志就在这个问题中?@rumbdolaf那么为什么要发布“IOException('连接关闭…')呢?因为这是从我的母语翻译回来的消息。下面5行是正确的,另外9行也是正确的。我将编辑那个旧的,只是为了确定;-)
// Just log how much data there is...
byte[] buffer = new byte[8 * 1024];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
Console.WriteLine(bytesRead);
}