[Winsock/C++] vraagje over UDP verkeer

Pagina: 1
Acties:

  • Unicron
  • Registratie: November 2001
  • Laatst online: 19-12 18:47
Hoi,

Ik las op internet dat er een probleem kan onstaan wanneer je CAsyncsocket gebruikt in combinatie met high speed UDP verkeer. Wanneer er een pakketje binnenkomt roept de CAsyncsocket class the onreceive callback functie aan om te laten weten dat er data beschikbaar is. In deze functie roep je dan de receive functie aan om de data uit te lezen. Nu blijkt het dus te kunnen gebeuren dat je dan gelijk 2 UDP pakketjes terugkrijgt, wat ik liever niet heb sinds ik dit niet kan detecteren.

Om dit te voorkomen zat ik eraan te denken om Winsock te gebruiken. In winsock zou ik dan met WSAEventSelect een event kunnen laten triggeren als er UDP data binnenkomt. Mijn vraag is of er bij Winsock dus wel precies 1 UDP pakketje per event wordt uitgelezen met de recv() functie?

  • MisterData
  • Registratie: September 2001
  • Laatst online: 18-12 15:28
Kun je misschien even vertellen welke CAsyncsocket-class je bedoelt cq. de broncode daarvan laten zien?Je kunt wel zien welke UDP-packets over de lijn gaan met een zogeheten 'packet-sniffer', google daar maar eens op :)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Een UDP packetje mag volgens mij ook gewoon gefragmenteerd worden. Dus dat je twee halfjes binnen krijgt bv. Als je daar niet op hoeft te checken, dan is het toch ook geen probleem als je er twee tegelijk krijgt? :)

  • MisterData
  • Registratie: September 2001
  • Laatst online: 18-12 15:28
Zoijar schreef op zaterdag 06 augustus 2005 @ 22:02:
Een UDP packetje mag volgens mij ook gewoon gefragmenteerd worden. Dus dat je twee halfjes binnen krijgt bv. Als je daar niet op hoeft te checken, dan is het toch ook geen probleem als je er twee tegelijk krijgt? :)
Heeft volgens mij iets met MTU (Maximum Transmission Unit) oid te maken, waarmee je aangeeft (in Windows ergens in het register) hoeveel gegevens in één pakket mogen voordat de data wordt gesplitst over twee. Zoek even op hoeveel da top jouw systeem is en kijk of dat lager is dan het aantal bytes dat je in een pakketje probeert te stoppen :)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

MisterData schreef op zaterdag 06 augustus 2005 @ 22:37:
Heeft volgens mij iets met MTU (Maximum Transmission Unit) oid te maken, waarmee je aangeeft (in Windows ergens in het register) hoeveel gegevens in één pakket mogen voordat de data wordt gesplitst over twee. Zoek even op hoeveel da top jouw systeem is en kijk of dat lager is dan het aantal bytes dat je in een pakketje probeert te stoppen :)
Dat neemt niet weg dat er ergens op de route misschien een host staat met een hele lage MTU, een of ander oude unix bak in een kelder. Overigens is het standaard geloof ik 536 bytes.

  • Unicron
  • Registratie: November 2001
  • Laatst online: 19-12 18:47
Dit is niet precies wat ik bedoel. Ik heb ook geen code om te laten zien. Ik ben zegmaar aan het brainstormen of ik beter CAsyncSocket kan gebruiken of beter Winsock.
Ik wil eigenlijk alleen maar weten als ik bijvoorbeeld pakketjes van 10 bytes verstuur, ik voor elke 10 bytes een event krijg?
Het kan bijv toch zo zijn dat de functie die de data uit de buffer haalt zolang bezig is dat er alweer 2x10 bytes instaan. Zal er dan bij de volgende keer dat je de data uitleest 10 of 20 bytes worden gegeven?

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Je hebt geen enkele garantie over hoe de data bij de client aankomt. Maar dat is geen verwijt aan welke class of library dan ook, dat is een gegeven bij het UDP/IP protocol. Packets kunnen zelfs in verkeerde volgorde aankomen, dus dat je eerst die laatste 20 bytes krijgt, en dan pas die eerste 10.

Je moet in principe alleen UDP gebruiken als het niet erg is als data niet of verkeerd aan komt. Anders moet je TCP gebruiken. En TCP is volledig streaming (byte voor byte), dus daar zal je iets van packet boundary bytes oid in moeten plaatsen om je packets te kunnen vinden. Je kan wel een soort minimale TCP laag op UDP bouwen... maar dan moet je precies weten wat en waarom je iets doet.

[ Voor 40% gewijzigd door Zoijar op 06-08-2005 22:58 ]


  • Unicron
  • Registratie: November 2001
  • Laatst online: 19-12 18:47
Dat van die volgorde weet ik ja en dat is ook niet het probleem. Ik wil gewoon dat pakketjes niet samen worden gevoegd. Dus als ik 10 bytes verstuur, wil ik ook 10 bytes ontvangen en niet die 10 bytes met daar achter nog eens het volgende pakketje geplakt.

Als ik het dus zo lees is de enige oplossing dus het meegeven van de grootte van het pakketje zodat je kan achterhalen of er meer dan 1 in de buffer staat.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Pakketjes samenvoegen? TCP heeft het Nagle algoritme, maar UDP toch niet? De documentatie zegt ook iets anders:
For datagram sockets, data is extracted from the first enqueued datagram
Overigens kan het natuurlijk wel gebeuren dat je 1 notificatie krijgt voor 2 pakketjes, maar die situatie is triviaal af te handelen.

Het lijkt me bovendien geen enkel probleem als het incidenteel gebeurt. Als je een pakketje van 20 bytes binnenkrijgt waar je er 10 verwacht knikker je het gewoon weg. Je gebruikt UDP, dus dan moet je protocol daar tegenkunnen.

Zoijar: De 536 byte MTU is het minimum voor IP. Default is het 1400 of zo, dat past precies in een Ethernet packet.

[ Voor 26% gewijzigd door MSalters op 07-08-2005 01:04 ]

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


  • Unicron
  • Registratie: November 2001
  • Laatst online: 19-12 18:47
MSalters schreef op zondag 07 augustus 2005 @ 01:00:
Pakketjes samenvoegen? TCP heeft het Nagle algoritme, maar UDP toch niet? De documentatie zegt ook iets anders:
[...]
Overigens kan het natuurlijk wel gebeuren dat je 1 notificatie krijgt voor 2 pakketjes, maar die situatie is triviaal af te handelen.

Het lijkt me bovendien geen enkel probleem als het incidenteel gebeurt. Als je een pakketje van 20 bytes binnenkrijgt waar je er 10 verwacht knikker je het gewoon weg. Je gebruikt UDP, dus dan moet je protocol daar tegenkunnen.

Zoijar: De 536 byte MTU is het minimum voor IP. Default is het 1400 of zo, dat past precies in een Ethernet packet.
met triviaal heb je het over het meegeven van de packetsize?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12 14:13
Dat zal moeten als je packets meer dan een factor 2 in grootte schelen. Maar ik bedoelde dat als je 1 notificatie krijgt, dat je dan niet aanneemt dat je 1 pakket ontvangen hebt, maar een loopje schrijft om alle beschikbare data te lezen.

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-12 21:53

.oisyn

Moderator Devschuur®

Demotivational Speaker

Unicron schreef op zaterdag 06 augustus 2005 @ 21:11:
Nu blijkt het dus te kunnen gebeuren dat je dan gelijk 2 UDP pakketjes terugkrijgt, wat ik liever niet heb sinds ik dit niet kan detecteren.
Weet je dat zeker? Zoals MSalters al zei, je kunt met een enkele leesactie nooit meerdere UDP packets ophalen, dat gebeurt packet voor packet, ookal heb je maar 1 notificatie gehad. Staat zelfs in de documentatie van CAsyncSocket. Je krijgt dus één hele packet per keer, geen halve en ook geen dubbele. Ik hoor hier mensen praten over fragmentatie, maar volgens mij heb je daar in de application layer geen last van; packets worden door het OS weer samengevoegd, en als er één mist wordt ie volgens mij gewoon in z'n geheel gedropped.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Unicron
  • Registratie: November 2001
  • Laatst online: 19-12 18:47
.oisyn schreef op maandag 08 augustus 2005 @ 11:30:
[...]


Weet je dat zeker? Zoals MSalters al zei, je kunt met een enkele leesactie nooit meerdere UDP packets ophalen, dat gebeurt packet voor packet, ookal heb je maar 1 notificatie gehad. Staat zelfs in de documentatie van CAsyncSocket. Je krijgt dus één hele packet per keer, geen halve en ook geen dubbele. Ik hoor hier mensen praten over fragmentatie, maar volgens mij heb je daar in de application layer geen last van; packets worden door het OS weer samengevoegd, en als er één mist wordt ie volgens mij gewoon in z'n geheel gedropped.
Ik had het ergens op internet gelezen en heb het nog nooit zelf gezien. Ik dacht alleen dat dit misschien een reden was waarom iedereen CAsyncSocket 'evil' noemt en bij winsock zweert.
Ik heb ondertussen ook een discussie gehad met iemand anders en je behoort inderdaad zoals jij zegt altijd maar 1 pakketje tegelijk te krijgen.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-12 21:53

.oisyn

Moderator Devschuur®

Demotivational Speaker

CAsyncSocket gebruikt ook gewoon winsock hoor :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1