[Win32 / C++] I/O Completion Ports

Pagina: 1
Acties:

  • RetepV
  • Registratie: Juli 2001
  • Laatst online: 05-06 15:39

RetepV

ALLES valt te repareren

Topicstarter
Heeft iemand hier al eens TCP socket I/O met I/O Completion Ports geprogrammeerd?

Ik zit met het probleem dat connects prima afgehandeld worden, maar:

1. als GetQueuedCompletionStatus() retourneert ik niet altijd altijd *alle* data krijg, soms maar 16 bytes (van bijvoorbeeld 30 bytes, mijn buffer is 2000 bytes groot).
2. als ik dan de rest van de data wil lezen (met recv), er geen data meer blijkt te zijn.

De data wordt wel volledig door de clients opgestuurd. De data blijft dus ergens in de socket layer hangen ofzo.

edit:

Als iemand mij kan verwijzen naar een URL waar alles goed en grondig uitgelegd wordt, zou ik ook al geholpen zijn. De voorbeelden die ik heb gevonden zijn of onbegrijpelijk, of te buggy voor woorden of ze vertonen gewoon hetzelfde probleem als ik nu heb.

[ Voor 21% gewijzigd door RetepV op 10-02-2003 17:19 ]

Macbook Pro


  • The End
  • Registratie: Maart 2000
  • Laatst online: 13:37

The End

!Beginning

Gebruik je de 'LPDWORD lpNumberOfBytes' parameter om te kijken in hoeverre de buffer gevuld is?
Zo ja, ik heb ergens gelezen (en bij mij is dat ook zo) dat als je asynchroon leest dat deze parameter niet geldig is en dat je op een andere manier achter de grootte moet komen. Helaas kan ik even niet vinden waar dat stond, maar ik ga nog even zoeken.

Verwijderd

RetepV schreef op 10 februari 2003 @ 16:42:
1. als GetQueuedCompletionStatus() retourneert ik niet altijd altijd *alle* data krijg, soms maar 16 bytes (van bijvoorbeeld 30 bytes, mijn buffer is 2000 bytes groot).
Dit is normaal: je TCP layer bepaald op een gegeven moment dat alle data wordt doorgestuurd naar jouw socket en dat kan in de meest ongelukkige 'chunks' gebeuren.
2. als ik dan de rest van de data wil lezen (met recv), er geen data meer blijkt te zijn.

De data wordt wel volledig door de clients opgestuurd. De data blijft dus ergens in de socket layer hangen ofzo.
Je moet dan natuurlijk niet zomaar recv gebruiken als je nog niet alle data hebt gehad (hoewel het op zich wel zou moeten werken), maar in plaats daarvan gewoon nog een read queuen (met WSARecv dus). Je volgende 'laag' moet vervolgens maar uitzoeken wanneer een compleet pakket/regel/whatever ontvangen is wat verder geprocessed kan worden. Dit werkte bij mij in ieder geval allemaal prima.
edit:

Als iemand mij kan verwijzen naar een URL waar alles goed en grondig uitgelegd wordt, zou ik ook al geholpen zijn. De voorbeelden die ik heb gevonden zijn of onbegrijpelijk, of te buggy voor woorden of ze vertonen gewoon hetzelfde probleem als ik nu heb.
Ik herinner me veel gehad te hebben aan twee (oudere) artikelen in een of andere MS journal oid (te lezen via MSDN/kb site), kan ze nu alleen niet meer vinden :(.

Verder kan ik je echt aanraden verder te prutsen met die completion ports, echt super hoe je daarmee schaalbaarheid/thread management kado krijgt.

  • RetepV
  • Registratie: Juli 2001
  • Laatst online: 05-06 15:39

RetepV

ALLES valt te repareren

Topicstarter
Verwijderd schreef op 10 februari 2003 @ 19:30:
[fragmenting van data door de TCP stack]

Dit is normaal: je TCP layer bepaald op een gegeven moment dat alle data wordt doorgestuurd naar jouw socket en dat kan in de meest ongelukkige 'chunks' gebeuren.
Yep, ik had me dat wel gerealiseerd, echter totdat ik I/O Completion Ports gebruikte heb ik het nooit gezien. Als mijn pakketje klein genoeg was, werd hij niet gefragmenteerd door de TCP stack. Maar goed, dat fragmenteren is op zich niet zo'n probleem.
[met recv() volgende data lezen lukt niet]

Je moet dan natuurlijk niet zomaar recv gebruiken als je nog niet alle data hebt gehad (hoewel het op zich wel zou moeten werken), maar in plaats daarvan gewoon nog een read queuen (met WSARecv dus).
Precies, het zou volgens mij ook wel moeten werken, want IOCP zit gewoon bovenop de winsock2 laag. Daarbij gebruik ik alleen IOCP op de listen socket waarop ik connecties accepteer. De connected socket is niet geassocieerd met een completion port en is gewoon met socket() gecreeerd.
Je volgende 'laag' moet vervolgens maar uitzoeken wanneer een compleet pakket/regel/whatever ontvangen is wat verder geprocessed kan worden. Dit werkte bij mij in ieder geval allemaal prima.
Yep, maar dat wil ik dus niet :). Maar goed, ik ga nog even verder testen met een metwerk sniffer. Het *kan* natuurlijk zijn dat de transfer van de data door de verzender vroegtijdig wordt afgebroken.
Verder kan ik je echt aanraden verder te prutsen met die completion ports, echt super hoe je daarmee schaalbaarheid/thread management kado krijgt.
Inderdaad. Het concept is geweldig, alleen is het nogal klote om te debuggen vanwege het multithreading. De schaalbaarheid is perfekt, als al je threads bezet zijn start je er gewoon een paar nieuwe op :). Dit zouden ze in Linux moeten stoppen (zit er misschien al in hoor :)).

Ik ga nog maar eens even verder zoeken, misschien is het toch een bug van mezelf :). IOCP wordt natuurlijk ook al lang volop door IIS gebruikt, dus ik mag er wel van uit gaan dat de bugs er uit zijn. Tnx!

Als iemand anders nog hulp kan bieden: laat je niet tegenhouden! Het is een lastig iets. In mijn geval is het voornamelijk lastig omdat ik het in een bestaand programma probeer in te passen.

Macbook Pro


  • RetepV
  • Registratie: Juli 2001
  • Laatst online: 05-06 15:39

RetepV

ALLES valt te repareren

Topicstarter
Nog even voor mensen die hier ook mee bezig zijn. Het boek 'Programming Server-Side Application for Windows 2000' van J.Richter en J.Clark (Microsoft Press) is redelijk goed.

Ook de volgende link is wel interessant: http://www.whiningdog.net...ng/Windows/20021115-IOCP/

Macbook Pro