[C#] Maximale throughput met UDP sockets

Pagina: 1
Acties:
  • 100 views sinds 30-01-2008
  • Reageer

  • Niek
  • Registratie: Februari 2001
  • Laatst online: 22-04 06:47

Niek

f.k.a. The_Surfer

Topicstarter
Ik ben bezig om een UDP server/client te maken in C# en loop tegen het probleem aan dat het moeilijk is de maximale snelheid te halen. Hier een stukje code die het probleem beschrijft:
C#:
1
2
3
4
5
6
7
8
9
10
int maxlength = 2050;
byte[] data = new byte[maxlength]; // Data om te verzenden

IPEndPoint sender = new IPEndPoint("192.168.0.1", 10000); // IP/port om naar toe te zenden
EndPoint Remote = (EndPoint)(sender);

while(true) {
  newsock.SendTo(data, 0, data.Length, SocketFlags.None, Remote);
  // Thread.Sleep(1);
}

Voor de leesbaarheid heb ik bepaalde gedeeltes en exceptions weggehaald.

De code hierboven zal niet goed werken, omdat zo snel mogelijk packets worden verzonden: de buffer van de router zal vollopen en bijna alle packets worden gedropt. Als ik de Thread.Sleep(1) uitcomment, zal dit probleem niet optreden, maar is de throughput maximaal 1MB/s (wat niet genoeg is).

Ik zoek dus een elegantere oplossing voor dit probleem, wellicht met een variable sleep die < 1ms aankan. TimeSpan ticks gebruiken werkt helaas niet, omdat je daarmee ook niet < 1ms kan sleepen. Het liefst wil ik niet p/invoke gebruiken om daarmee usleep() van de win32 api te gebruiken.

Iemand een ideetje?

À vaincre sans péril, on triomphe sans gloire - Pierre Corneille


  • dotcode
  • Registratie: Augustus 2003
  • Laatst online: 19-04 14:26

dotcode

///\00/\\

Om dit op te lossen zijn er netwerk algs die je kan implementeren. Ik kan ze even gaan opratelen (je kan het ook gewoon zelf opzoeken), je kan ook het boek van tanenbaum pakken over netwerkenen. Daar kan je dan zelf een keuze maken.

  • Niek
  • Registratie: Februari 2001
  • Laatst online: 22-04 06:47

Niek

f.k.a. The_Surfer

Topicstarter
Ik weet van die algoritmes, maar dan blijft het probleem bestaan dat je niet < 1 ms kan sleepen in .NET. Vandaar dat ik op zoek ben naar een manier om dit te omzeilen, of eleganter op te lossen dan simpelweg de usleep() van win32 aan te roepen.

À vaincre sans péril, on triomphe sans gloire - Pierre Corneille


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-04 02:19
Je kunt om te beginnen proberen uit te zoeken wat de maximale packet size (MTU) die je kunt halen. Op een ethernet LAN is dat meestal 1500 bytes (waar ethernet, IP en UDP headers nog vanaf moeten). Vervolgens verstuur je data packets van die grootte, zodat je zoveel mogelijk data in één packet hebt zitten zonder dat het packet opgesplitst moet worden (wat sowieso alleen maar voor IPv4 werkt).

Verder geef je zelf al aan dat het probleem 'm er in zit dat je de buffer van je router (of de ontvangende computer) te snel opvult. Het gaat er dus alleen maar om dat je niet te veel pakketjes tegelijk stuurt in een periode, maar dat betekent niet dat je per milliseconde maar één pakketje mag versturen. Je kunt je throughput dus verhogen door (bijvoorbeeld) drie pakketjes te sturen en dan een milliseconde te wachten; je hebt dan niet per se een hogere resolutie timer nodig.

Sowieso is dit een vrij lastig onderwerp; als je een robuust protocol wil ontwerpen moet je al een manier bedenken om de MTU dynamisch uit te zoeken (niet heel lastig, maar daarvoor zijn wel een relatief low-level socket API nodig), om de optimale snelheid te bepalen (al redelijk tricky) en om verloren pakketjes te detecteren en opnieuw te verzenden. Behoorlijk ingewikkeld dus, terwijl TCP dat al automatisch voor je doet. Grote kans dat je dus beter gelijk TCP kunt gebruiken.

[ Voor 3% gewijzigd door Soultaker op 07-11-2005 18:17 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Waarom neem je aan dat het een MTU probleem is? Natuurlijk, als je iets dropt, dan drop je een heel packet, dus transfer unit spelen mee. Maar voorzover ik weet is Nagle een TCP algortime; UDP packets worden toch niet gemerged?

Ik weet niet of de router een source quench ICMP ondersteunt. Dat was in elk geval vroeger de oplossing, maar het werkt niet op een hostile network. Binnen je LAN zou het echter wel moeten kunnen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein