Ich kommuniziere zwischen zwei Prozessen auf verschiedenen Maschinen über eine Pipe, wobei IO-Vervollständigungsroutinen verwendet werden.
Gelegentlich wird, wenn die Vervollständigungsroutine für WriteFileEx aufgerufen wird, der Vervollständigungsroutinenparameter dwErrorCode 0 (d. h. kein Fehler), GetOverlappedResult true (d. h. kein Fehler) zurück, aber dwNumberOfBytesTransfered stimmt nicht mit nNumberOfBytesToWrite in dem Aufruf von WriteFileEx überein. Ich sehe dies jedoch nur auf dem Client-Ende der Pipe.
Wenn die Anzahl der übertragenen Bytes nicht mit der Anzahl der Bytes übereinstimmt, die übertragen werden sollen, wie kann dies als Erfolg gewertet werden?
So wird das Handle des Clients für die Pipe erstellt:
%Vor%Kann jemand sehen, warum das passieren würde?
Danke
BEARBEITEN:
Der relevante WriteFileEx-Code ist wie folgt:
%Vor%Dabei ist LPPIPEINST wie folgt deklariert:
%Vor%Und der erste Aufruf von CompletedWriteRoutine erhält den Parameter lpOverlap, der so deklariert ist:
%Vor%BEARBEITEN:
Nachdem ich versucht hatte, die überlappende Struktur neu zu initialisieren, wie Harry vorgeschlagen hatte, bemerkte ich etwas Eigenartiges.
I memset
Die OVERLAPPED
Struktur vor jedem WriteFileEx
auf Null, und ungefähr 1/5000 Abschluss-Routine Callbacks, der Parameter cbWritten
und der OVERLAPPED
Struktur InternalHigh
Mitglied wurde jetzt auf die Größe des vorherigen gesetzt Nachricht anstelle der letzten Nachricht. Ich fügte der Datei sowohl auf der Client- als auch auf der Server-Seite der Pipe innerhalb der Completion-Routinen etwas Protokollierung hinzu, und die an beiden Enden gesendeten und empfangenen Daten stimmten genau überein (und die korrekten, erwarteten Daten). Dies enthüllte dann, dass in der Zeit, die zum Schreiben der Daten in eine Datei benötigt wurde, das InternalHigh
-Member in der OVERLAPPED
-Struktur geändert wurde und nun die Größe der erwarteten Nachricht widerspiegelt ( cbWritten
bleibt die alte Nachrichtengröße) . Ich habe die Dateiprotokollierung entfernt und kann das Problem jetzt wie ein Uhrwerk mit diesem Code reproduzieren:
Es scheint so zu sein, dass manchmal die Completion-Routine aufgerufen wird, bevor die OVERLAPPED
-Struktur und der Eingabeparameter der Completion-Routine aktualisiert wird. Ich verwende MsgWaitForMultipleObjectsEx(eventLast, hEvent, INFINITE, QS_POSTMESSAGE, MWMO_ALERTABLE);
für die Abschlussroutinen, die unter Windows 7 64 bit aufgerufen werden.
Diese MSDN-Seite lautet:
"Das System verwendet die OVERLAPPED-Struktur nicht, nachdem die Vervollständigungsroutine aufgerufen wurde, so dass die Vervollständigungsroutine den von der überlappten Struktur belegten Speicher freigeben kann."
... also anscheinend, was dieser Code reproduzieren kann, sollte nie passieren?
Ist das ein WINAPI-Fehler?
% FILE_FLAG_NO_BUFFERING
zum Aufruf CreateFile
hinzugefügt - habe das Problem seitdem nicht gesehen. Danke an alle, die sich für Ihre Zeit geäußert haben.
Tags und Links c named-pipes c++ windows winapi