我正在使用Stream
来序列化BinaryReader
中的对象:
class MyClass
{
public void Read(Stream stream)
{
BinaryReader reader = new Reader(stream);
this.someField = reader.ReadSomething(); // IOException
}
}
在一种情况下的问题是,如果我从NetworkStream
读取,服务器在发送数据后立即关闭连接。这导致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)
class Record
{
public void Read(Stream stream)
{
BinaryReader reader = new BinaryReader(stream);
byte contentType = reader.ReadByte();
byte majorVer = reader.ReadByte();
byte minorVer = reader.ReadByte();
ushort payloadSize = reader.ReadUInt16();
if(contentType == 21) // Alert
{
Alert alert = new Alert();
alert.Read(stream);
}
}
}
class Alert
{
public void Read(Stream stream)
{
BinaryReader reader = new BinaryReader(stream);
byte level = reader.ReadByte(); // IOException
byte desc = reader.ReadByte();
}
}
答案 0 :(得分:2)
不应该成为问题。如果服务器确实只发送了所有数据,然后以有序的方式关闭了流,那么应该能够获取它发送的所有数据。如果连接以不那么有序的方式终止,或者在其他地方丢弃,你会看到一个问题,并且可能如果你继续尝试从中读取,它已经返回它已经关闭的事实。
如果您不使用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
...它应该只是退出循环。如果这样做但你现有的代码抛出,你需要检查你在阅读代码中做出的假设(你还没有发布)。
答案 1 :(得分:0)
导致IOException(“Connection closed ...”)
这可能是由你的身边关闭连接然后尝试从中读取而引起的。远程关闭应该只是导致EOS条件在API中出现的各种方式之一。
API假设传入的TCP FIN意味着连接已关闭是一个重大错误:它可能是关闭,另一个方向仍然可以运行。