C# SocketException 不会被捕获
我的代码中发生了一个非常奇怪的情况。我正在开发 ac# 聊天客户端-服务器应用程序。当我关闭服务器时,我希望客户端自动关闭。客户端使用 StremReader 从 TcpClient 对象读取。客户端处于 while 循环中,它读取一行(StreamReader.ReadLine()),然后对其读取的行执行一些操作。 当服务器关闭时,我也会关闭服务器端的 tcp 连接。因此,我希望客户端看到由 readline 引起的 SocketException,捕获它并退出。但异常不会被捕获! 这是客户端循环代码:
while (true)
{
try
{
ricev = read.ReadLine();
}
catch(SocketException exc)
{
//It never gets in here
}
chat.Invoke(showMessage, ricev);
}
当我关闭服务器时,Visual Studio 告诉我 System.dll 中引发了“System.Net.Sockets.SocketException”第一次机会异常,但我无法捕获它。为什么会发生这种情况?我还尝试用块捕获任何通用异常
catch
{
}
,但这也不起作用。
任何帮助将不胜感激!
编辑:在尝试了更多次之后,我实际上发现 SocketException 根本没有被引发。正如我在评论中所说,这太奇怪了,在相反的情况下,当客户端在服务器之前关闭时,会引发异常,我可以这样做。 我真的不知道发生了什么......
i have a really weird sitation going on in my code. I'm developping a c# chat client-server application. When i close the server i want the client to be automatically closed. The client is reading from the TcpClient object using a StremReader. The client is in a while loop where it reads a line(StreamReader.ReadLine()) and then doing some operations with the line it reads.
When the serever gets closed, i also close the tcp connection server-side. So, i'm expecting the client to see a SocketException caused by the readline, catch it and exit. But the exception doesn't get caught!
Here's the client loop code:
while (true)
{
try
{
ricev = read.ReadLine();
}
catch(SocketException exc)
{
//It never gets in here
}
chat.Invoke(showMessage, ricev);
}
When i close the server, visual studio tells me that a "System.Net.Sockets.SocketException" first-chance exception was raised in System.dll, but i cannot catch it. Why does that happen? i also tried to catch any generic exception with a
catch
{
}
block, but that doesn't work either.
Any help will be appreciated!
EDIT: after trying some more times, i actually found out that SocketException doesn't get raised at all. That's so weird, as i said in a comment, in the opposite situation, when the client gets closed before the server, the exception gets raised and i can canth it.
I don't really know what's going on....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这是因为 .Net 对发送/接收方法使用不安全的方法。您必须处理程序 Coontext 的
UnhandledException
This is because .Net uses unsafe methods for Send/Receive methods.you have to handle your Program Coontext's
UnhandledException
如果我很了解您的情况,那么当您在
TcpListener
对象“_server.Stop()
”调用Stop
方法时,它不会抛出 <当在流上调用Read
时,客户端出现 code>SocketException ...我不知道为什么会发生这种情况,但我有一个围绕它的工作基础。它是通过访问TcpListener
上的底层Socket
并对其调用Shutdown
来实现的:编辑: 您在评论:
如果正在停止
tcpListerner
“_server.Stop()
”,然后关闭从_server 获取的
方法,然后在客户端
。 AcceptTcpCleint()reader.ReadLine()
处将抛出IOException: 无法从传输连接读取数据:阻塞操作被调用中断到WSACcelBlockingCall
我自己测试了一下。If I understand you well the scenario is when you call
Stop
method atTcpListener
object "_server.Stop()
", it will not throwSocketException
at the client side when callRead
on the stream... I don't know why this is happening but I have a work ground around it. it is by accessing to the underlyingSocket
on theTcpListener
and callShutdown
on it:Edit: You stated at comment:
If are stopping the
tcpListerner
"_server.Stop()
" and then close theclients
getted from_server.AcceptTcpCleint()
method, then at the atreader.ReadLine()
will throwIOException: Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall
I tested it myself.如果您调用
Invoke
,异常很可能会被包装在TargetInvocationException
中。If you are calling
Invoke
, odds are that the exception will be wrapped in aTargetInvocationException
.调试器会拦截第一次机会异常并中断您。这是第二次机会异常让您进入 catch 块,这就是为什么您不会在第一次机会时进入
catch
块。有关详细信息,请参阅这篇文章。摘自我上面提到的文章
顺便说一句,您始终可以将调试器配置为在第一次出现异常时不停止。
First chance exceptions are intercepted by the debugger and interrupts you. It is the second chance exception that gets you into your catch block and that's why you do not get into your
catch
block on first chance. See this article for more information.Extracted from the article I mentioned above
On a side note, you can always configure your debugger to not stop on first chance exceptions.
当关闭服务器套接字时,另一端会收到零字节的消息。这表明服务器已正确关闭:
http://msdn.microsoft.com/en-us/library/8s4y8aff.aspx
仅在特殊情况下抛出异常 - 例如,如果您在客户端连接到服务器计算机时重新启动服务器计算机 - 而不是正常的程序流。
当发生这种情况时,
ReadLine()
操作也不应该抛出异常,而只是返回null
:http://msdn.microsoft.com/en-us /library/system.io.streamreader.readline.aspx
When you close the server socket, the other side receives a message of zero bytes. This indicates that the server has closed down properly:
http://msdn.microsoft.com/en-us/library/8s4y8aff.aspx
Exceptions are thrown only for exceptional situations - for instance if you reboot the server computer while your client was connected to it - not for normal program flow.
The
ReadLine()
operation should also not throw an exception but simply returnnull
when this happens:http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline.aspx
我以前遇到过这个问题,结果发现我已经激活了“抛出 CLR 异常时中断并且没有取消选中它”,
所以,检查一下您没有取消选中此功能
按 Alt+Ctr + E
向下滚动到公共运行时语言异常,并确保取消选中“抛出”复选框。
我希望这对你有帮助。
I've this problem before and turn's out that I've been activate "Break when CLR Exception thrown and didn't uncheck it back"
So,check of you didn't uncheck this feature by
Press Alt+Ctr + E
scroll down to Common Runtime Language Exception and make sure to uncheck "Thrown" Check box.
I hope this help you.