2012-05-10 29 views
1

我很抱歉,如果这已经回答了SO。我看了但没有找到它。我的情况是,我的客户可以通过在本地网络上连接到他们的TCP服务器,也可以通过Verizon调制解调器进行远程连接。 (我正在使用.NET 3.5 - C#)Socket.Connect抛出和错误我不能捕获

当我从任何一个连接,事情都很好。但是如果我不小心在“错误的”网络上(例如:我在星巴克并登录到他们的无线网络,我忘记了,认为我在Verizon卡上,所以现在我尝试登录)服务器拒绝连接。精细。但是我的Try/Catch没有捕获任何东西......它只是退出例程(如果我通过线程池调用它),或者如果直接调用它,它会挂起。

下面是代码(失败的:m_clientSocket.Connect(IPEND)):

tcpConnectionObject passObject = new tcpConnectionObject(serverIP, serverPORT); 
     ThreadPool.QueueUserWorkItem(new WaitCallback(SRVR_CONNECT.connectToTCP), passObject); 

这就是所谓的:

tcpConnectionObject passedTCPObject = (tcpConnectionObject) obj; 
if (checkNetStat(passedTCPObject) == false) 
{ 
    updateStatus(false); 
    return; 
} 

try 
{ 
    m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    IPAddress ip = IPAddress.Parse(passedTCPObject.ipString); 
    int iPortNo = System.Convert.ToInt16(passedTCPObject.portString); 
    IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo); 

    m_clientSocket.Connect(ipEnd); 
    if (m_clientSocket.Connected) 
    { 
      updateStatus(true); 
      //Wait for data asynchronously 
      WaitForData(); 
    } 
} 
catch (SocketException e) 
{ 
    updateStatus(false); 
    return; 
} 
catch (Exception e) 
{ 
    updateStatus(false); 
    return; 
} 

updateStatus(true); 
return ; 

我使用线程池调用这个从一个WinForm表单的SHOW()方法。当我这样做时,我的表单显示,但状态永远不会改变(它应该是任何结果)如果我把一个调试器,并开始逐步执​​行,我到达Socket.Connect()调试器只是退出方法,我的表单显示。我从未打过我的任何捕获物。

我试过了Socket可以产生的每一个错误,但它从来没有捕获任何东西。当我运行我的调试器时,只要我点击该行,它就退出我的方法,但没有错误可以追踪。

+0

此基础上挂着,如果你直接调用它,我问你为什么htink它退出后台线程不通知。我会假设后台线程也挂着 – JaredPar

+0

你有调试器设置为停止时引发异常(不只是未处理)? –

+0

@IgbyLargeman建议检查我在想什么。如果你通过,它不会步入异常? – MStodd

回答

0

如果您确实在异步等待(如您在注释中说明的那样),那么您在实际得到异常之前可能正在退出try/catch块。

+0

除了它永远不会到达那条线(我可以看到)当我在调试器中遍历时,它只是在我点击connect时退出该方法。除非调试器被线程池所困惑...... – MarkJoel60

+0

如果你正在做任何异步操作,你将有多个线程;这很难追查。你可以验证你在WaitForData中做了什么以及它是否是“异步等待数据”? –

+0

彼得,我会接受你的回答,因为我认为你或多或少是正确的......我有一个更完整的答案,但你的理智检查将我转向正确的道路...... – MarkJoel60

0

它退出你的方法,因为你的catch块有一个return语句。你告诉它明确地返回。

+0

是的,但是我在每次回归时都放了一个断点,并且没有一个被击中。 – MarkJoel60

0

好吧,我认为彼得是在正确的轨道上。它似乎像调试器只是跳过我的连接线,并在等待Socket.Connect()完成时移动到下一行(如果有意义的话)?

下面是对代码有效的更改。 ..我移动数据包的创建,并将回调定义从“WaitForData”中移出并使用beginConnect方法。然后,我可以设置一个超时,这让我知道失败 - 这样的代码更改为这个:

try 
     { 
      m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      // Cet the remote IP address 
      IPAddress ip = IPAddress.Parse(passedTCPObject.ipString); 
      int iPortNo = System.Convert.ToInt16(passedTCPObject.portString); 
      // Create the end point 
      ipEnd = new IPEndPoint(ip, iPortNo); 

      Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      SocketPacket theSocPkt = new SocketPacket(); 
      if (m_pfnCallBack == null) 
      { 
       m_pfnCallBack = new AsyncCallback(OnDataReceived); 
      } 
      // Give It 5 Seconds to connect 
      IAsyncResult result = socket.BeginConnect(ipEnd, m_pfnCallBack, theSocPkt); 
      bool success = result.AsyncWaitHandle.WaitOne(5000, true); 

      if (!success) 
      { 
       socket.Close(); 
       throw new ApplicationException("Server Refused Connection"); 
      } 
      // Success 
      updateStatus(true); 
     } 
     catch (SocketException e) 
     { 
      updateStatus(false); 
      return; 
     } 
     catch (Exception e) 
     { 
      updateStatus(false); 
      return; 
     }