c# SocketException不会被捕获

本文关键字:SocketException | 更新日期: 2023-09-27 18:02:31

我的代码中出现了一个非常奇怪的情况。我正在开发一个c#聊天客户端-服务器应用程序。当我关闭服务器时,我希望客户端自动关闭。客户端正在使用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.Net.Sockets。在System.dll中引发了"第一次机会异常",但我无法捕获它。为什么会这样呢?我还尝试用

捕获任何泛型异常。
catch
{
}

块,但这也不起作用。

任何帮助将不胜感激!

编辑:在尝试了更多的时间后,我实际上发现SocketException根本没有被提出。这太奇怪了,正如我在评论中所说,在相反的情况下,当客户端在服务器之前关闭时,会引发异常,我可以处理它。我真的不知道发生了什么....

c# SocketException不会被捕获

如果我理解你的情况是当你在TcpListener对象" _server.Stop() "上调用Stop方法时,它不会在流上调用Read时在客户端抛出SocketException…我不知道为什么会这样,但我有一个工作的基础。它是通过访问TcpListener上的底层Socket并在其上调用Shutdown:

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

编辑:您在注释中声明:

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

如果正在停止tcpListerner " _server.Stop() ",然后关闭从_server.AcceptTcpCleint()方法获得的clients,那么在reader.ReadLine()将抛出IOException: Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall,我自己测试了它。

如果您正在调用Invoke,则异常将被包装在TargetInvocationException

visual studio告诉我" system.net.socket.socketexception "在System.dll中引发了第一次机会异常,但无法捕获它。为什么会这样呢?

第一次异常被调试器截获并中断您。这是第二次机会异常,使您进入捕获块,这就是为什么您没有在第一次机会进入catch块。更多信息请参阅本文。

摘自上面提到的文章

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

附带说明一下,您可以始终将调试器配置为在第一次出现异常时不停止。

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

如果远程主机使用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

我以前遇到过这个问题,结果证明我已经激活了"当CLR异常抛出时中断并且没有取消检查它"

检查一下你没有通过
取消选中这个特性按Alt+ ctrl + E向下滚动到公共运行时语言异常,并确保取消选中"抛出"复选框。我希望这对你有帮助。

这是因为。net为发送/接收方法使用了不安全的方法。你必须处理你的程序上下文的UnhandledException