2011-03-04 20 views
6

Oldukça basit bir Eşzamansız UDP dinleyicim var, hizmet olarak ayarlandı ve şimdi bir süredir oldukça iyi çalışıyor ancak son zamanlarda bir SocketException An existing connection was forcibly closed by the remote host'da çöktü. Şu anda üç sorum var:C# Async UDP dinleyicisi SocketException

  1. Buna neden oluyor? (UDP soketlerinin bir bağlantısı olduğunu düşünmedim)
  2. Test amacıyla, nasıl çoğaltıtabilirim?
  3. İstisnai nasıl temizleyebilirim, böylece her şey çalışmaya devam edecek mi?

    private Socket udpSock; 
    private byte[] buffer; 
    public void Starter(){ 
        //Setup the socket and message buffer 
        udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
        udpSock.Bind(new IPEndPoint(IPAddress.Any, 12345)); 
        buffer = new byte[1024]; 
    
        //Start listening for a new message. 
        EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0); 
        udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock); 
    } 
    
    private void DoReceiveFrom(IAsyncResult iar){ 
        try{ 
         //Get the received message. 
         Socket recvSock = (Socket)iar.AsyncState; 
         EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0); 
         int msgLen = recvSock.EndReceiveFrom(iar, ref clientEP); 
         byte[] localMsg = new byte[msgLen]; 
         Array.Copy(buffer, localMsg, msgLen); 
    
         //Start listening for a new message. 
         EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0); 
         udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock); 
    
         //Handle the received message 
         Console.WriteLine("Recieved {0} bytes from {1}:{2}", 
              msgLen, 
              ((IPEndPoint)clientEP).Address, 
              ((IPEndPoint)clientEP).Port); 
         //Do other, more interesting, things with the received message. 
        } catch (ObjectDisposedException){ 
         //expected termination exception on a closed socket. 
         // ...I'm open to suggestions on a better way of doing this. 
        } 
    } 
    

    istisna recvSock.EndReceiveFrom() satırında atılıyor:

Kodum aşağıdaki gibi görünür.

cevap

13

, UDP soket da ICMP mesaj alma ve alındıkları zaman durumlar atma gibi görünüyor. Belki bu düşük seviye durum güncellemeleri için harika, ama bunu sinir bozucu buldum.

Öncelikle

public const int SIO_UDP_CONNRESET = -1744830452; 

Sonra bu mesajları görmezden düşük seviye io kontrolünü ayarlamak sihirli sayısını tanımlar:

var client = new UdpClient(endpoint); 
client.Client.IOControl(
    (IOControlCode)SIO_UDP_CONNRESET, 
    new byte[] { 0, 0, 0, 0 }, 
    null 
); 
+0

Great Man! Merhaba, ICMP mesajları alma ve alındıklarında istisnalar atma konusunda aynı sorun vardı. Kodlama numaranız tarafından çözüldü! – Kevan

+0

@Kyle, sonunda bunu tamamen test etmek için uğraştım! Bu istisnanın gerçek kök nedeniydi. Referans olarak, hem cevabınızı hem de Jim'i kullanarak sona erdim, böylece bir istisna olsa bile dinleyici yeniden başlatılacak. – chezy525

+0

Kırık Bağlantı. Bu cevap, bağlantıyı güncellemek veya bağlantının işaret ettiği bilgileri içerecek şekilde değiştirilmelidir. –

2

Bir paket bir şekilde kesilmişse veya başka şekilde tam olarak teslim edilmiyorsa, bu hatayı UDP ile gördüm. En azından ben düşünürüm olan şey bu. Onu asla güvenilir bir şekilde kopyalayamadım.

SocketException'u yakalamanızı, günlüğe kaydetmenizi (ardından) kaydetmenizi ve ardından bu soketi atmanızı öneririm. Sonra tekrar Starter çağırır:

this forum thread itibaren
catch (SocketException) 
{ 
    // log error 
    udpSock.Close(); 
    Starter(); 
} 
+0

Bu benim bunu kadar sona erdi, ama yine de istiyorum aslında bu istisnaya neyin yol açtığını (yani doğru olduğunu düşündüğünüzü ispatlayın) öğrenin. – chezy525

+0

@ chezy525 Bu soket istisnasının genellikle soketinizdeki ICMP "Hedef/Bağlantı Noktası/etc. Ulaşılamaz" iletilerinden kaynaklandığına inanıyorum. Sadece dinliyorsan nasıl alırsın, emin değilim. Sadece bir düşünce. – Kongress

+0

system.net izlemeyi etkinleştirmeyi deneyin ve –