2012-03-27 1 views
0

Ich benutze $ SUB zum ersten Mal und sind auf dieses Problem gestoßen. Sowohl Client als auch Server verwenden überlappende Operationen und hier ist die spezifische Situation, mit der ich ein Problem habe.Überlappte Nachricht namens Pipe, ERROR_MORE_DATA und CancelIoEx

Kunde

C1. Stellt eine Verbindung zum Server her.
C2. Sendet die Nachricht größer als ein Pipepuffer und der Puffer wird an den überlappenden Lesevorgang im Server übergeben.
C3. Sendet den Sendevorgang erfolgreich ab.

Server

S1. Erstellt und wartet auf den Client.
S2. Wenn der Client verbunden ist, liest er die Nachricht.
S21. Da Nachricht nicht in den Puffer (ERROR_MORE_DATA) passt, wird es Teil für Teil gelesen.

Es scheint mir, dass es keine Möglichkeit gibt zu sagen, wann die ganze Nachricht als isolierte Einheit abgebrochen wird. Insbesondere, wenn der Client die Sendeoperation abbricht, empfängt der Server nicht die gesamte Nachricht, nur einen Teil davon, und die nachfolgende Leseoperation kehrt mit ERROR_IO_PENDING (in meinem Fall) zurück, was bedeutet, dass keine Daten zum Lesen und Lesen vorhanden sind wurde in die Warteschlange gestellt. Ich würde erwarten, dass der Leser durch eine Art Mittel informiert wird, dass die Nachricht annulliert wurde, damit der Leser darauf reagieren kann.

Die relevante Dokumentation ist jedoch über MSDN streuen, so dass ich auch etwas fehlt. Ich würde es sehr schätzen, wenn jemand etwas Licht darauf werfen könnte. Vielen Dank.

Antwort

0

Sie haben Recht, es gibt keine Möglichkeit zu sagen.

Wenn Sie die Writefile teilweise abbrechen, wird nur ein Teil der Nachricht geschrieben, sodass nur dieser Teil vom Server gelesen wird. Es werden keine "Buchhaltungs" -Informationen darüber gesendet, wie groß die Nachricht sein würde, bevor sie abgebrochen wird - was gesendet wird, sind nur die Rohdaten.

Also die Antwort ist: Nicht die IO abbrechen, nur warten, bis es erfolgreich ist.

Wenn Sie tun, müssen IO teilweise durch brechen, sollten Sie wahrscheinlich die Verbindung trennen und von Anfang an erneut starten, genau wie Sie für einen Netzwerkausfall.

(Sie können Ihre ÜBERLAPPVERBINDUNG Struktur überprüfen, um herauszufinden, wie viel tatsächlich geschrieben, und führen von dort aus, aber wenn man wollte, dass Sie wahrscheinlich aufheben würde tun, nur nicht die IO an erster Stelle.)

Warum wollten Sie die IO trotzdem abbrechen? Welche Umstände lösen diese Anforderung aus?

+0

Mein Client (Pipe Writer) hat eine Ereignisschleife, die auch andere Dinge erledigt, abgesehen von dem Senden von Nachrichten durch eine Pipe. Aus diesem Grund ist das Senden von Pipes asynchron, der Client blockiert nicht für immer, wenn der Server (Reader) Probleme hat, Nachrichten zu verarbeiten und den Puffer voll zu füllen. Wenn der Sendevorgang asynchron ist, wird der Overlap-Ereignishandle zum WaitForMultibleObjects-Aufruf hinzugefügt. –

+0

Danke, dass Sie vorgeschlagen haben, das Rohr zu schließen. Das mache ich jetzt und es funktioniert für meine Situation. –

+0

@PeterVrabel haben Sie 'MsgWaitForMultipleObject' und' CoWaitForMultipleHandles' gesehen? Mit ihnen können Sie auch andere Nachrichten wie Benutzereingaben aktivieren. Dadurch können Sie möglicherweise länger warten, bis Sie IO abbrechen müssen. – Ben

Verwandte Themen