2010-04-10 19 views
10

Bağlam: C# linux perl uygulamasını taşıyorum, sunucu bir udp bağlantı noktasında dinler ve tek bir udp soketi üzerinden uzak istemcilerle birden çok eşzamanlı iletişim kurar. Test sırasında, udp sunucusuna yüksek hacimli paketler gönderiyorum, istemcileri yeni bağlantıların kaydedildiği sunucuyu gözlemlemek için rasgele yeniden başlatıyorum. Sorun şu: Bir udp istemcisini öldürdüğümde, o istemci için hala sunucuda veri olabilir. Sunucu bu verileri göndermeye çalıştığında, "iceri yok" mesajının bir icmp'i olur ve sonuçta sokette bir istisna oluşur.Bir C# udp soket istisnasından incelikle nasıl kurtarılır?

C# async işleyicisini soketle ilişkilendirmeyi denediğimde bu soketi yeniden kullanamıyorum, istisna hakkında şikâyet ediyor, bu nedenle sunucu bağlantı noktasındaki udp soketini kapatıp yeniden açmam gerekiyor. Bu problemin tek yolu bu mu ?, elbette, udp soketinin teknik olarak bir "sabitleme" yolu vardır, UDP soketleri bir uzak soketin durumunu bilmemeli mi?

Herhangi bir yardım veya işaretçi çok takdir edilecektir. Teşekkürler.

cevap

1

Sanırım haklısınız: 'sunucu farkında olmamalı'. UDP paketini, açık/kapalı olabilecek bir IP/port'a gönderirseniz, sunucunun varış noktasına ulaşıp ulaşmadığını bilmenin bir yolu yoktur.

Sunucunun bilmesinin tek yolu, istemcinin bir ACK geri göndermesini sağlamaktır. (Ayrıca, hem istemci hem de sunucu, kayıp paketler durumunda geçerli mekanizmaları yeniden göndermelidir).

Nikolai'nin sözler sonra kontrol ettim docs:

Yani açıkça başka bir şey kodunuzda (veya .Net UDP uygulaması ile)

DÜZENLEME oluyor. Ve gerçekten de UDP'yi kullanırken .Net'in “bağlı” ya da “bağlantısız” olmasının bir ayrımı var.

Böyle kodu kullanıyorsanız:

sonra kişiye,
 UdpClient udpClientB = new UdpClient(); 
    udpClientB.Send(sendBytes, sendBytes.Length, "AlternateHostMachineName", 11000); 

gönderebilirsiniz: o zaman görünüşe

Ancak böyle bir kod kullanırsanız 'bağlı' olan

UdpClient udpClient = new UdpClient(11000); //sourceport 
try{ 
    udpClient.Connect("www.contoso.com", 11000); //'connect' to destmachine and port 
    // Sends a message to the host to which you have connected. 
    Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there?"); 
    udpClient.Send(sendBytes, sendBytes.Length); 

'bağlanmadan' seçersiniz.

Ben senin kod neye benzediğini emin değilim, ancak bir 'bağlantı'

+1

Eh üstlenmez komutların doğru kümesini kullanıyor olmadığını kontrol etmek faydalı olabilir, teknik olarak ağ yığını uzak uç, bazı uygulamaların gerçekleştirdiği bir icmp "hedefe ulaşılamaz" sinyali gönderirse kapalı bir udp portunun farkındadır. Belki de geçici olarak icmp'i engellemeyi deneyeceğim ve aynı istisnaları alıp alamayacağımı göreceğim ... –

+0

@gearoid O zaman bile, soketin bağlantı noktası olup olmadığını veya – Toad

+1

olduğunu bilmemesi için başka bir paket göndermeli. * bağlı * ve * bağlı olmayan * UDP soketleri arasında bir ayrım var. Birincisi için, çekirdek, ICMP hatasını hangi uygulamaya yönlendirecek? ikincisi için, bu yüzden hata teslim edilmez. Hepsi soket portu atamasına kadar kaynar. O zaman .NET'den nasıl çalıştığını bilmiyorum. –

İlgili konular