2010-03-09 20 views
9

Jak wiemy dla UDP otrzymać używamy Socket.ReceiveFrom lub UdpClient.receiveJak ustawić rozmiar bufora pod Socket UDP? C#

Socket.ReceiveFrom zaakceptować tablicę bajtów, aby umieścić dane w udp.

UdpClient.receive powraca bezpośrednio bajt tablica gdzie dane są

Moje pytanie jest, że jak ustawić rozmiar bufora wewnątrz gniazda. Myślę, że OS utrzymuje swój własny bufor do odbioru danych UDP, prawda? na przykład, jeśli pakiet udp zostanie wysłany do mojego komputera, system operacyjny umieści go w buforze i odczeka nas na Socket.ReceiveFrom lub UdpClient.receive, prawda?

Jak mogę zmienić rozmiar tego wewnętrznego bufora?

Próbowałem Socket.ReceiveBuffSize, to nie ma żadnego wpływu na wszystko dla UDP, i to wyraźnie powiedziane, że to do okna TCP. Zrobiłem też wiele eksperymentów, które dowodzą, że Socket.ReceiveBufferSize NIE jest dla UDP.

Czy ktoś może podzielić się spostrzeżeniami na temat wewnętrznego bufora UDP?

Dzięki

Widziałem kilka postów tutaj, na przykład,

http://social.msdn.microsoft.com/Forums/en-US/ncl/thread/c80ad765-b10f-4bca-917e-2959c9eb102a

Dave powiedział, że Socket.ReceiveBufferSize można ustawić wewnętrzny bufor dla UDP. Nie zgadzam się.

Eksperyment zrobiłem to tak:

27 gospodarze wysłać paczkę 10KB udp mi obrębie sieci LAN w tym samym czasie (przynajmniej prawie). Mam pętlę while do obsługi każdego z pakietów. Dla każdego pakietu tworzę wątek, który go obsługuje. Użyłem UdpClient lub Socket do odbioru pakietów.

Straciłem około 50% pakietów. Sądzę, że jest to impuls wysyłania UDP i nie poradzę sobie z nimi wszystkimi na czas.

Dlatego chcę, aby zwiększyć rozmiar bufora dla UDP. powiedz, jeśli zmienię rozmiar bufora na 1MB, wtedy 27 * 10KB = 270KB danych może zostać zaakceptowanych w buforze, prawda?

Próbowałem zmieniając Socket.ReceiveBufferSize wielu wielu wartości, i to po prostu nie ma wpływu w ogóle.

Każdy może pomóc?

Odpowiedz

9

używam .NET UDPClient często i zawsze używał Socket.ReceiveBufferSize i mają dobre wyniki. Wewnętrznie wywołuje Socket.SetSocketOption z parametrem ReceiveBuffer. Oto niektóre szybkie, proste, można przetestować kod z:

public static void Main(string[] args) 
{ 
    IPEndPoint remoteEp = null; 
    UdpClient client = new UdpClient(4242); 
    client.Client.ReceiveBufferSize = 4096; 

    Console.Write("Start sending data..."); 
    client.Receive(ref remoteEp); 
    Console.WriteLine("Good"); 

    Thread.Sleep(5000); 
    Console.WriteLine("Stop sending data!"); 
    Thread.Sleep(1500); 

    int count = 0; 
    while (true) 
    { 
    client.Receive(ref remoteEp); 
    Console.WriteLine(string.Format("Count: {0}", ++count)); 
    } 
} 

Spróbuj wyregulować wartości przekazanej do ReceiveBufferSize. Testowałem wysyłanie stałego strumienia danych przez 5 sekund i otrzymałem 10 pakietów. Następnie zwiększyłem x4 i następnym razem otrzymałem 38 pakietów.

będę szukać do innych miejsc w sieci, gdzie można być spada pakietów. Zwłaszcza, że ​​wspominasz na swojej other post, że wysyłasz pakiety 10KB. 10 KB będzie pofragmentowane, gdy zostanie wysłane do pakietów o rozmiarze MTU. Jeśli jakikolwiek 1 pakiet z serii zostanie upuszczony, cały pakiet zostanie upuszczony.

+0

@heavyd: Dziękuję za odpowiedź. Mój kod jest bardzo podobny do twojego. ale jeśli jesteś zainteresowany, możesz zrobić prosty eksperyment. Mamy oddzielne dwie klasy - Serwer i Klient. w swoim Client.cs, wystarczy użyć UdpClient, aby wysłać 200 pakietów (każdy po 10 KB) do lokalnego portu 8888. (niezależnie od portu) w twoim Server.cs, ciągle odbierasz tak, jak pokazano w twoim kodzie oczywiście, proszę najpierw uruchomić serwer. Mój wynik to 90% pakietów, które można odebrać. Chodzi o to, że wysyłanie UDP to seria, do której dociera zbyt wiele pakietów, a serwer nie może obsłużyć. a przepełnienie bufora. – Jack

+0

Tak, i czy mówisz, że dostosowując ReceiveBufferSize z wartości, powiedz "4096" do wyższej wartości, powiedz "4 * 4096" nic nie robi? – heavyd

+0

@heavyd, czy mogę wiedzieć, jaki jest górny limit dla ReceiveBufferSize? – Jack

7

Problem z ustawieniem opcji ReceiveBufferSize polega na ustawieniu jej bezpośrednio po utworzeniu obiektu UdpClient. Miałem ten sam problem z moimi zmianami, które nie zostały odzwierciedlone podczas pobierania wartości ReceiveBufferSize.

UdpClient client = new UdpClient() 
//no code inbetween these two lines accessing client. 
client.Client.ReceiveBufferSize = somevalue 
Powiązane problemy