1

これがSOで回答された場合はお詫び申し上げます。見ましたが見つかりませんでした。私の状況では、顧客はローカルネットワーク上にいるか、Verizonモデムを介してリモートで接続することにより、TCPサーバーに接続できます。(私は.NET 3.5-C#を使用しています)

どちらからでも接続すれば大丈夫です。しかし、誤って「間違った」ネットワークに接続した場合はどうなりますか(例:スターバックスにいて、ワイヤレスネットワークにログオンしています。Verizonカードを使用していると思っていたので、今はログインしようとしています)サーバーは拒否します繋がり。罰金。しかし、私のTry / Catchは何もキャッチしていません...それは単にルーチンを終了するか(スレッドプールを介して呼び出している場合)、直接呼び出すとハングします。

コードは次のとおりです(失敗します:m_clientSocket.Connect(ipEnd)):

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からこれを呼び出します。

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

これは、フォームのSHOW()メソッドで呼び出されます。このようにすると、フォームは表示されますが、ステータスは変更されません(結果によって変更されるはずです)デバッガーを配置して実行をステップ実行すると、Socket.Connect()に到達します。デバッガーはmthodを終了するだけで、フォームに表示されます。キャッチをヒットしたことはありません。

Socketが生成する可能性のあるすべてのエラーを試しましたが、何もキャッチされません。デバッガーを実行すると、その行に到達するとすぐにメソッドが終了しますが、キャッチ可能なエラーはありません。

4

3 に答える 3

0

catch ブロック内に return ステートメントがあるため、メソッドを終了します。明示的に返すように指示しています。

于 2012-05-10T16:17:19.300 に答える
0

OK、ピーターは正しい道を進んでいたと思います。Socket.Connect() が終了するのを待っている間、デバッガーは単純に 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;
       }
于 2012-05-11T03:12:04.407 に答える
0

(コメントで述べているように)本当に非同期で待機している場合は、実際に例外を取得する前に try/catch ブロックを終了している可能性があります。

于 2012-05-10T16:18:46.093 に答える