C# Socket 捕获不到异常
- C# code
IPEndPoint myServer = new IPEndPoint(IPAddress.Parse(textBox_ServerIp.Text), 5588); _tcpListener = new TcpListener(myServer); _tcpListener.Start(); while (true) { try { TcpClient ss = _tcpListener.AcceptTcpClient(); Thread t = new Thread(RecieveData); t.Start(ss); } catch (Exception ex) { Common.CommonRoutine.HandlingExceptions(ex); } } public void RecieveData(object obj) { TcpClient tcpClient = obj as TcpClient; StateObject stateObject = new StateObject() { WorkSocket = tcpClient }; while (true) { try { if (tcpClient != null && tcpClient.Client != null ) tcpClient.Client.BeginReceive(stateObject.Buffer, 0, stateObject.Buffer.Length, SocketFlags.None, RecieveComplete, stateObject); stateObject.ResetEvent.WaitOne(); // Thread.Sleep(1000); //MessageBox.Show("s"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } public void RecieveComplete(IAsyncResult result) { StateObject state = (StateObject)result.AsyncState; TcpClient tcpClient = state.WorkSocket; if (tcpClient == null || tcpClient.Client == null || !tcpClient.Client.Connected) { return; } int bytesRed = tcpClient.Client.EndReceive(result); if (bytesRed > 0) { byte[] receData = new byte[bytesRed]; Array.Copy(state.Buffer, 0, receData, 0, bytesRed); byte[] realData = OperateCmdData.RestoreReceData(receData); if (OperateCmdData.JudgeisCompleteData(realData)) { byte[] sendData = OperateCmdData.AnalysisMessageId(receData); if (sendData.Length > 19) tcpClient.Client.Send(sendData); } } state.ResetEvent.Set(); }
RT 客户端异常关闭socket服务端程序会直接退出,捕获不到任何异常。如果在BeginReceive那里睡1S钟就可以捕获到“远程主机强迫关闭了一个现有的连接。”异常。
- C# code
tcpClient.Client.BeginReceive(stateObject.Buffer, 0, stateObject.Buffer.Length, SocketFlags.None, RecieveComplete, stateObject); stateObject.ResetEvent.WaitOne(); Thread.Sleep(1000);
如果不睡1S的话程序会自动退出。看VS的输出消息有
在 System.Net.Sockets.SocketException 中第一次偶然出现的“System.dll”类型的异常
求解。3Q。
[解决办法]
- C# code
while (true) { try { if (tcpClient != null && tcpClient.Client != null ) tcpClient.Client.BeginReceive(stateObject.Buffer, 0, stateObject.Buffer.Length, SocketFlags.None, RecieveComplete, stateObject); stateObject.ResetEvent.WaitOne(); // Thread.Sleep(1000); //MessageBox.Show("s"); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
[解决办法]
[解决办法]
try
{
TcpClient ss = _tcpListener.AcceptTcpClient();
Thread t = new Thread(RecieveData);
t.Start(ss);
}
catch (Exception ex) { Common.CommonRoutine.HandlingExceptions(ex); }
这类程序逻辑没有道理。
try...catch....不是捕获子线程的异常的,或者说异常的机制根本不是抛出给父线程。
[解决办法]
比如说你写
try
{
注册并启动另外的线程
}
catch
{
....
}
这么这个catch不等子线程启动就已经执行过去了,捕获什么呢?结果你的另外的子线程根本没有捕获任何异常。你显然是写这个try...catch...没有用。
[解决办法]
if (bytesRed > 0)
在这个之前要判断其是否等于0,等于0代表断开,就直接return了。
[解决办法]
c#的这类功能没做过,做过C++的,不过的确子线程的异常try catch 不是直接抛给父的。你可以尝试用log记载下来。
[解决办法]
[解决办法]
建议你辅助线程里直接处理异常,如果实现不行,那么就这样写:
- C# code
try { //可能发生异常的代码块 } catch (Exception ex) { Action act = new Action(() => { throw ex; }); this.Invoke(act); }
[解决办法]
可以用个全局变量接收子线程异常的内容,然后,主线程查这个值。。从而传到主线程
[解决办法]
我建议定义一个自己的异常类,在需要捕获的任何一个线程里用不同的实例编码(对象的唯一性)来记录,这样也可第一时间找到程序的出错地方,之后再进行单步调试
[解决办法]
- VB.NET code
Dim msgex As String = "" '出错消息的传替,=“” 无错,!!’=================== try 。。。 msgex = "" ‘正常来 End If Catch ex As Exception msgex = ex.Message '出错消息的传替,=“” 无错,!这个只是提示消息!从一个线程传替到UI End Try ‘。。。’===================’=================== If msgex = "" Then '出错消息的传替,=“” 无错,!! ' MsgBox("发送完毕!", , "^-^ 提示 ^-^ ") Else MsgBox("发送被中断!" & msgex, , "^-^ 提示 ^-^ ") '由异步线程传替过来的出错消息。 End If
[解决办法]
[解决办法]
http://www.cnblogs.com/henusfs/archive/2009/06/18/UDP.html
[解决办法]
[解决办法]
单步跟踪一下,呵呵呵
[解决办法]
RecieveComplete里面你判断了read的字节数,但如果字节数为0,其实就表示客户端已经断开了链接,但你好像没有处理
[解决办法]
你的问题很简单,还有另一法,使用异步委托调用方式,可以传替出错从子线程到UI线程,
如果用VB.NET 来做,一行异步调用指令可以完成,记住异步委托哦
[解决办法]
给你个异步调用的例,参考后改入你的环境中,,
BeginInvoke(New EventHandler(AddressOf Addmsg), "服务端已启动,正在等待连接......") '线程内用委托办法做别的事
‘===================
Private Sub Addmsg(ByVal addtxt As System.Object, ByVal e As System.EventArgs) '将消息只写入LISTBOX1
'非UI线程调用窗体控件,保证线程安全。与聊天实现无关。
If addtxt.ToString <> "" Then
If ListBox1.Items.Count > 127 Then
clientmsg.Text = ""
ListBox1.Items.Clear()
End If
ListBox1.Items.Add(addtxt.ToString)
End If
' GC.Collect()
End Sub
[解决办法]
给你个异步调用的例,参考后改入你的环境中,,
BeginInvoke(New EventHandler(AddressOf Addmsg), "服务端已启动,正在等待连接......") '线程内用委托办法做别的事
‘===================
Private Sub Addmsg(ByVal addtxt As System.Object, ByVal e As System.EventArgs) '将消息只写入LISTBOX1
'非UI线程调用窗体控件,保证线程安全。与聊天实现无关。
If addtxt.ToString <> "" Then
If ListBox1.Items.Count > 127 Then
clientmsg.Text = ""
ListBox1.Items.Clear()
End If
ListBox1.Items.Add(addtxt.ToString)
End If
' GC.Collect()
End Sub
[解决办法]