我的代码中有一个非常奇怪的引用。我正在开发一个c#chat客户端 - 服务器应用程序。当我关闭服务器时,我希望客户端自动关闭。客户端使用StremReader从TcpClient对象读取。客户端处于while循环中,它读取一行(StreamReader.ReadLine()),然后对其读取的行执行一些操作。 当serever关闭时,我也关闭了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根本没有被提升。这是如此奇怪,正如我在评论中所说,在相反的情况下,当客户端在服务器之前关闭时,异常会被提升并且我可以解决它。 我真的不知道发生了什么......
答案 0 :(得分:1)
如果我理解你的情况是在Stop
对象“TcpListener
”处调用_server.Stop()
方法,则在通话时它不会在客户端抛出SocketException
流上的Read
......我不知道为什么会这样,但我有一个工作场所。通过访问Socket
上的基础TcpListener
并在其上调用Shutdown
:
_server.Stop();
_server.Server.Shutdown(SocketShutdown.Both);//now at your "read.ReadLine();" will throw SocketException
修改:您在评论中说明了这一点:
实际上我正在关闭accept方法上监听器返回的tcpclient。 connClient.Close()
如果要停止tcpListerner
“_server.Stop()
”然后关闭clients
来自_server.AcceptTcpCleint()
方法,那么at reader.ReadLine()
会抛出{{}我自己测试了它。
答案 1 :(得分:0)
如果您正在调用Invoke
,则可能会将异常包含在TargetInvocationException
中。
答案 2 :(得分:0)
visual studio告诉我一个“System.Net.Sockets.SocketException” 在System.dll中引发了第一次机会异常,但我无法抓住 它。为什么会这样?
调试器拦截了第一次机会异常并中断了您。这是第二次机会异常,让你进入你的阻挡区块,这就是为什么你没有第一次进入catch
区块的原因。有关详细信息,请参阅此article。
摘自我上面提到的文章
第一次机会异常是否意味着我的代码存在问题?第一次机会异常消息通常并不意味着存在问题 代码中的问题。适用于处理的应用程序/组件 优雅的异常,第一次机会异常消息让 开发人员知道遇到异常情况并且是 处理。
另一方面,您始终可以将调试器配置为不会因第一次机会异常而停止。
答案 3 :(得分:0)
关闭服务器套接字时,另一端收到零字节消息。这表示服务器已正确关闭:
如果远程主机使用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
答案 4 :(得分:0)
我之前遇到过这个问题并且转过来我已经激活了#34;在CLR异常被抛出时中断并且没有取消选中"
所以,检查一下你没有取消选中此功能 按Alt + Ctr + E. 向下滚动到Common Runtime Language Exception并确保取消选中" Thrown"复选框。 我希望这能帮到你。
答案 5 :(得分:-2)
这是因为.Net对发送/接收方法使用了不安全的方法。你必须处理你的程序Coontext的UnhandledException