读书人

C# Socket 捕获不到错误

发布时间: 2012-05-01 12:48:58 作者: rapoo

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);                }               } 


[解决办法]

探讨

引用:

C# code

while (true)
{
try
{
if (tcpClient != null && tcpClient.Client != null )
tcpClient.Client.Beg……
这一部分以另外的线程操作,而不是UI主线程。

你说的方法试了,没用,监听的……

[解决办法]
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
[解决办法]
探讨
引用:

建议你辅助线程里直接处理异常,如果实现不行,那么就这样写:
C# code

try
{
//可能发生异常的代码块

}
catch (Exception ex)
{
Action act = new Action……


试了。。没用。。

[解决办法]
http://www.cnblogs.com/henusfs/archive/2009/06/18/UDP.html
[解决办法]
探讨
C# code

while (true)
{
try
{
if (tcpClient != null && tcpClient.Client != null )
tcp……

[解决办法]


单步跟踪一下,呵呵呵
[解决办法]
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




[解决办法]

探讨

try
{
TcpClient ss = _tcpListener.AcceptTcpClient();
Thread t = new Thread(RecieveData);
……

读书人网 >C#

热点推荐