C# SocketException 不会被捕获

发布于 2024-11-19 18:44:48 字数 806 浏览 3 评论 0原文

我的代码中发生了一个非常奇怪的情况。我正在开发 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

不气馁 2024-11-26 18:44:49

这是因为 .Net 对发送/接收方法使用不安全的方法。您必须处理程序 Coontext 的 UnhandledException

This is because .Net uses unsafe methods for Send/Receive methods.you have to handle your Program Coontext's UnhandledException

甜味拾荒者 2024-11-26 18:44:48

如果我很了解您的情况,那么当您在 TcpListener 对象“_server.Stop()”调用 Stop 方法时,它不会抛出 <当在流上调用 Read 时,客户端出现 code>SocketException ...我不知道为什么会发生这种情况,但我有一个围绕它的工作基础。它是通过访问 TcpListener 上的底层 Socket 并对其调用 Shutdown 来实现的:

_server.Stop();
_server.Server.Shutdown(SocketShutdown.Both);//now at your "read.ReadLine();" will throw SocketException

编辑: 您在评论:

实际上我正在关闭accept方法上的监听器返回的tcpclient。 connClient.Close()

如果正在停止 tcpListerner_server.Stop()”,然后关闭从 _server 获取的客户端。 AcceptTcpCleint() 方法,然后在 reader.ReadLine() 处将抛出 IOException: 无法从传输连接读取数据:阻塞操作被调用中断到WSACcelBlockingCall我自己测试了一下。

If I understand you well the scenario is when you call Stop method at TcpListener object "_server.Stop()", it will not throw SocketException at the client side when call Read 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 underlying Socket on the TcpListener and call Shutdown on it:

_server.Stop();
_server.Server.Shutdown(SocketShutdown.Both);//now at your "read.ReadLine();" will throw SocketException

Edit: You stated at comment:

actually i'm closing the tcpclient returned by the listener on the accept method. connClient.Close()

If are stopping the tcpListerner "_server.Stop()" and then close the clients getted from _server.AcceptTcpCleint() method, then at the at reader.ReadLine() will throw IOException: Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall I tested it myself.

北城挽邺 2024-11-26 18:44:48

如果您调用 Invoke,异常很可能会被包装在 TargetInvocationException 中。

If you are calling Invoke, odds are that the exception will be wrapped in a TargetInvocationException.

早乙女 2024-11-26 18:44:48

Visual Studio 告诉我“System.Net.Sockets.SocketException”
System.dll 中引发了第一次机会异常,但我无法捕获
它。为什么会发生这种情况?

调试器会拦截第一次机会异常并中断您。这是第二次机会异常让您进入 catch 块,这就是为什么您不会在第一次机会时进入 catch 块。有关详细信息,请参阅这篇文章

摘自我上面提到的文章

第一次机会异常是否意味着我的代码中存在问题?第一次机会异常消息通常并不意味着存在问题
代码中的问题。对于处理的应用程序/组件
优雅地处理异常,第一次机会异常消息让
开发人员知道遇到了特殊情况并且已
已处理。

顺便说一句,您始终可以将调试器配置为在第一次出现异常时不停止。

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?

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

Does a first chance exception mean there is a problem in my code? First chance exception messages most often do not mean there is a
problem in the code. For applications / components which handle
exceptions gracefully, first chance exception messages let the
developer know that an exceptional situation was encountered and was
handled.

On a side note, you can always configure your debugger to not stop on first chance exceptions.

铜锣湾横着走 2024-11-26 18:44:48

当关闭服务器套接字时,另一端会收到零字节的消息。这表明服务器已正确关闭:

如果远程主机使用 Shutdown 方法关闭 Socket 连接,并且已接收到所有可用数据,则 Receive 方法将立即完成并返回零字节。

http://msdn.microsoft.com/en-us/library/8s4y8aff.aspx

仅在特殊情况下抛出异常 - 例如,如果您在客户端连接到服务器计算机时重新启动服务器计算机 - 而不是正常的程序流。

当发生这种情况时,ReadLine() 操作也不应该抛出异常,而只是返回 null

返回值

输入流中的下一行,如果到达输入流末尾则为 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:

If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the Receive method will complete immediately and return zero bytes.

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 return null when this happens:

Return value

The next line from the input stream, or null if the end of the input stream is reached.

http://msdn.microsoft.com/en-us/library/system.io.streamreader.readline.aspx

恋你朝朝暮暮 2024-11-26 18:44:48

我以前遇到过这个问题,结果发现我已经激活了“抛出 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文