2016-04-15 3 views
0

Я в настоящее время пишу код в C# и ему необходимо связаться с программой, написанной в VB6 через сокеты. <br/> Когда программа VB6 не запущена, моя программа на C# выдает исключение SocketException.
То, что я сделал, - это исключение, но я заметил, что он продолжит бросать это исключение, пока программа VB6 не запустится снова. <br/><br/> Метод ReceiveFrom (...) находится в бесконечном цикле, поэтому, когда программа VB6 запускается снова, она может принимать данные. <br/><br/> Интересно, есть ли лучший способ справиться с этим.

С # код выглядит следующим образом ...SocketException правильная обработка в C#

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)' в течение некоторого времени, когда эта ошибка происходит, вместо того, чтобы постоянно иметь цикл, попытайтесь подключиться и выбросить ошибку. Это зависит от общего поведения этих двух приложений, хотя, может быть, вам нужна очень быстрая проверка, возможно, если приложение VB не работает, вы можете некоторое время спятить приложение C#, а затем снова проверить. Это зависит от вас, но в целом обработанные ошибки сокетов - это не огромная сделка, хотя это может быть идеальным, чтобы не бросать постоянно. – pay

+0

+1 на Thread.Sleep (x) в блоке catch ... , хотя мне интересно, есть ли способ реорганизовать, как сокет прослушивает данные. например, с помощью 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

Я пробовал это и скорректировал условие на доступное> 1 .., поскольку доступное свойство может быть 0 или 1, даже если нет данных из сети. –

+0

Это также исключает исключение, вызванное сокет, который является приятным. Затем я добавил Thread.Sleep в блок else. :) –

Смежные вопросы