Winsock & Overlapped I/O
-
Hallo!
ich arbeite mich gerade durch alle I/O-Möglichkeiten von Windows und nutze dafür Sockets. Momentan bin ich bei Overlapped I/O (noch ohne Completion Ports) und nutze keine Events, sondern Callback-Routinen. Jetzt habe ich aber ein paar Fragen:Um die Serverhauptschleife schlafen zu legen, nutzte ich bisher WSAWaitForMultipleEvents(), welches auf ein bestimmtes Event horcht (innerhalb der Overlapped-Struktur der AcceptEx(), also wartet auf neue Verbindungen). Nebenbei wird die Funktion aber auch beendet, wenn irgendeine andere Overlapped-Completion erfolgt und die Completion-Routine ausgeführt wird, oder? Dabei sollte das Event-Objekt aber nicht auf signaled gesetzt werden, da ja z.B. irgendein WSARecv ein anderes Event-Objekt nutzt als das von AcceptEx(). Ich hoffe, das stimmt soweit.
Wie sieht das jetzt mit SleepEx() aus? Irgendwie erscheint mir diese Funktion noch lokrativer als WSAWaitForMultipleEvents(), da ich nicht erst irgendein Dummy-Event-Array erstellen muss. Andererseits wird SleepEx() durch eine Overlapped-Completion beendet, und ohne Event weiß ich ja nicht, ob es sich hierbei um eine neue Verbindung oder um ein WSARecv() handelt. Warum ich das wissen muss?
// Unterschleife in der Serverhauptschleife // Wird nur bei einer neuen Verbindung unterbrochen und wartet sonst auf // WSASend()/WSARecv()-Completions, führt diese aus und startet die Schleife neu for(;;) { std::cout << "Warte auf asynchrone Ereignisse..." << std::endl; int result = WSAWaitForMultipleEvents(1, event_array, FALSE, WSA_INFINITE, TRUE); if(result == WSA_WAIT_FAILED) throw "Das asynchrone Warten auf eine neue Verbindung ist fehlgeschlagen!"; if(result != WAIT_IO_COMPLETION) break; } // Mache ein WSARecv() auf die akzeptierte Verbindung...Ich hoffe, ich konnte mich halbwegs verständlich artikulieren!
-
Also ich hab's zumindest nicht verstanden.
Also nicht den Teil, wieso du nach SleepEx() wissen willst, was dich eigentlich aufgeweckt hat.
Sollte doch egal sein.Wenn du wissen musst ob Aktion X stattgefunden hat, kannst du ja im Completion-Callback für Aktion X irgendwas machen. Idealerweise gleich ganz darauf reagieren, so dass die "Hauptschleife" überhaupt nur mehr ca. so aussieht:
while (runServer) SleepEx(1000);D.h. wenn eine neue Verbindung reingekommen ist, dann wird dein "AcceptCallback" aufgerufen. Das WSAAccept für die nächste Verbindung rufst du dann gleich im AcceptCallback auf.
Genauso eventuelle Fehlerbehandlungen.
-
Nun ja, aber gerade wegen Performance nutze ich nicht WSAAccept(), sondern AcceptEx(). Diese Funktion ist zwar auch Overlapped, aber bietet keine Callbacks an. Scheinbar besteht die auf Events als Ereignismechanismus. Da sind Completion Ports scheinbar doch die saubere Lösung. Gibt es einen Grund, warum AcceptEx() keine Callbacks kann?
-
Wieso mischt du Callbacks und Event-Benachrichtigung?!?
Nur damit du AcceptEx verwenden kannst?
Pffff.Premature Optimization usw.
Mach' dir mal nicht unnötig das Leben schwer, den Unterschied wirst du wohl nicht merken.