2016-04-15 30 views
0

私は現在C#にコードを書いており、ソケットを介してVB6で書かれたプログラムと通信する必要があります。 <br/> VB6プログラムが実行されていないとき、私のC#プログラムはSocketExceptionをスローします。
私が行ったことは例外をキャッチしていましたが、VB6プログラムが再び実行されるまでその例外がスローされ続けることに気付きました。 <br/><br/> ReceiveFrom(...)メソッドは無限ループになっているため、VB6プログラムが再度実行されるとデータを受信できます。 <br/><br/> これを処理するより良い方法があるのだろうかと思います。
C#コード
C#でのSocketExceptionの適切な処理

internal class SocketConnection : Connection 
{ 
    private Socket socket; 
    private EndPoint localEndPoint; 
    private IPEndPoint remoteIPEndPoint; 

    internal SocketConnection(int localPortNumber, IPAddress remoteIPAddress, int remotePortNumber) 
    { 
     IPEndPoint localIPEndPoint = new IPEndPoint(
      GetLocalIPAddress(), 
      localPortNumber); 

     socket = new Socket(
      localIPEndPoint.Address.AddressFamily, 
      SocketType.Dgram, 
      ProtocolType.Udp); 

     socket.Bind(localIPEndPoint); 

     localEndPoint = (EndPoint)localIPEndPoint; 
     Thread receiver = new Thread(() => Receive()); 
     receiver.Start(); 

     remoteIPEndPoint = new IPEndPoint(remoteIPAddress, remotePortNumber); 
    } 

    private void Receive() 
    { 
     byte[] msg = new Byte[256]; 
     while (true) 
     { 
      try 
      { 
       socket.ReceiveFrom(msg, ref localEndPoint); 
       buffer = Encoding.ASCII.GetString(msg).TrimEnd('\0'); 
      } 
      catch (SocketException) 
      { 
       buffer = string.Empty; 
      } 
     } 
    } 
    private IPAddress GetLocalIPAddress() 
    { 
     var host = Dns.GetHostEntry(Dns.GetHostName()); 
     foreach (var ip in host.AddressList) 
     { 
      if (ip.AddressFamily == AddressFamily.InterNetwork) 
      { 
       return ip; 
      } 
     } 
     throw new Exception("Local IP Address Not Found!"); 
    } 

    protected override void Interrogate(string message) 
    { 
     socket.SendTo(Encoding.ASCII.GetBytes(message), remoteIPEndPoint); 
    } 
} 
+1

ありません。例外が処理される限り、一般的には問題ありません。ループが絶えず接続してエラーをスローするのではなく、エラーが発生したときにプロセスが 'Thread.Sleep(x)'を実行するように振る舞いを変更することができます。これは、これらの2つのアプリケーションの一般的な動作に依存しますが、VB Appが動作していない場合はC#アプリケーションをしばらくスリープ状態にしてから再度確認することができます。それはあなた次第ですが、一般的にソケットエラーを処理するのは大したことではありませんが、常にスローしないのが理想的かもしれません。 – pay

+0

catchブロックのThread.Sleep(x)の+1 ... ソケットがデータをリッスンする方法をリファクタリングする方法があるのだろうかと思うが、 System.IO.Portsのように、DataReceivedイベントがあるので、Readメソッドを常にループする必要はありません。 –

答えて

1

あなたがソケットに読むために何かがあることを確認する必要がありReceiveFromを呼び出す前に...次のようになります。本当に

   int available = socket.Available; 
       if (available > 0) 
       { 
        socket.ReceiveFrom(msg, 0, Math.Min(msg.Length, available), SocketFlags.None, ref localEndPoint); 
        buffer = Encoding.ASCII.GetString(msg).TrimEnd('\0'); 
       } 
+0

ネットワークからのデータがなくても利用可能なプロパティが0または1である可能性があるので、これを試して、使用可能な> 1に条件を調整しました.. –

+0

これは良いソケットによってスローされた例外も排除します。次に、elseブロックにThread.Sleepを追加しました。 :) –

関連する問題