NetworkStream.Read 挂起/阻塞的原因有哪些?
MSDN 文档似乎表明 NetworkStream.Read 将始终立即返回。如果没有找到数据,它将返回 0。但是,我当前部署了一些代码,仅在某些情况下(我还没有弄清楚哪些情况),NetworkStream.Read 似乎挂起。这是我从转储文件中收集的堆栈跟踪
00000000705ae850 000007fef784f60d DomainBoundILStubClass.IL_STUB(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags) 00000000705ae930 000007fef785c930 System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags, System.Net.Sockets.SocketError ByRef) 00000000705ae9b0 000007ff004eb668 System.Net.Sockets.NetworkStream.Read(Byte[], Int32, Int32) 00000000705aea40 000007fef784e6ae MySocketStuff.SocketConnectCallback(System.IAsyncResult) 00000000705aeb20 000007fef84f2bbb System.Net.LazyAsyncResult.Complete(IntPtr) 00000000705aeb90 000007fef7853c7b System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 00000000705aebe0 000007fef784e5d3 System.Net.ContextAwareResult.Complete(IntPtr) 00000000705aec40 000007fef7d027f9 System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr) 00000000705aeca0 000007fef8b9815e System.Net.Sockets.Socket.ConnectCallback() 00000000705aed20 000007fef93e14c2 System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)
,我注意到 NetworkStrea.Read 实际上调用了 Socket.Receive,据我所知,它可能会阻塞。我只是不知道为什么有时会阻塞,有时不会。
MSDN documentation seems to suggest that NetworkStream.Read will always return immediately. If no data is found it returns 0. However, I have some code that is currently deployed, that only in some cases (and I haven't figured out which ones yet), NetworkStream.Read appears to hang. Here is the stack trace which i was able to gather from a dump file
00000000705ae850 000007fef784f60d DomainBoundILStubClass.IL_STUB(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags) 00000000705ae930 000007fef785c930 System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags, System.Net.Sockets.SocketError ByRef) 00000000705ae9b0 000007ff004eb668 System.Net.Sockets.NetworkStream.Read(Byte[], Int32, Int32) 00000000705aea40 000007fef784e6ae MySocketStuff.SocketConnectCallback(System.IAsyncResult) 00000000705aeb20 000007fef84f2bbb System.Net.LazyAsyncResult.Complete(IntPtr) 00000000705aeb90 000007fef7853c7b System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 00000000705aebe0 000007fef784e5d3 System.Net.ContextAwareResult.Complete(IntPtr) 00000000705aec40 000007fef7d027f9 System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr) 00000000705aeca0 000007fef8b9815e System.Net.Sockets.Socket.ConnectCallback() 00000000705aed20 000007fef93e14c2 System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object, Boolean)
I notice that the NetworkStrea.Read actually calls Socket.Receive which can be blocking as far as I understand. I just don't know why sometimes it would block and sometimes it would not.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
NetworkStream 文档的备注部分。阅读具有误导性。它说:
应该说:
The Remarks section of the documentation for NetworkStream.Read is misleading. It says:
It should say:
有时套接字缓冲区中已有数据,有时则可能没有。
看到 NetworkStream 块的一个常见原因是连接的每一端都期望另一端关闭。例如,如果您建立 HTTP 1.1 保持活动连接,但仍采用“读取直至连接关闭”方式获取内容。
Sometimes there'll be data already in the socket buffer and sometimes there won't, presuambly.
One common reason for seeing a
NetworkStream
block is if each side of the connection is expecting the other to close. For example, if you make an HTTP 1.1 keep-alive connection, but still do the "read until the connection is closed" way of getting content.处理 NetworkStream 时的一个常见错误是通过 Write 方法发送未完成的命令,这会导致连续的 Read 调用挂起。
请参阅以下尝试将用户名发送到打开的 FTP 端口的示例。它期望像 331 Please指定密码 这样的响应,但
Read
方法挂起:一个神奇的解决方案是将第一行替换为以下内容:
只需添加 \ r\n 短语放在命令末尾,一切都会开始按预期工作。
One common mistake while dealing with
NetworkStream
is sending unfinished commands viaWrite
method which causes a consecutiveRead
call hanging.See the below example that tries to send a user name to an opened FTP port. It expects a respond like 331 Please specify the password but the
Read
method hangs:A magic solution is to replace the first line with the following:
By simply adding \r\n phrase at the end of the command, everything will just start to work as expected.
如果没有数据可供读取,Read 方法将阻塞,直到有数据可用为止。如果您不想阻塞,请考虑使用异步套接字函数。
http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx
If no data is available for reading, the Read method will block until data is available. Consider using the Async Socket functions if you don't want to block.
http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx