[英]Reading data from NetworkStream when server closes immediately after sending
我正在使用BinaryReader
從Stream
序列化對象:
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();
}
}
這應該不是問題。 如果服務器確實只發送了所有數據,然后以有序的方式關閉流,那么您應該能夠獲取它發送的所有數據。 如果連接以一種不那么有序的方式終止,或者在其他地方丟棄,你可能會看到一個問題,並且可能在你已經返回它已經關閉的事實后繼續嘗試從中讀取。
如果您不使用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(“Connection closed ...”)
這更可能是因為你的一方關閉連接然后試圖從中讀取。 遠程關閉應該只是導致EOS條件在API中表現出來的各種方式之一。
如果傳入的TCP FIN意味着連接已關閉,那將是一個重大的錯誤:它可能是一個關閉,另一個方向仍然可以運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.