Die Dokumente für das TransmitFile winsock-Funktion sagt "Datei" und nicht "Dateideskriptor", also lautet die Antwort vielleicht nein? Wenn ich TransmitFile nicht verwenden kann, um Daten aus einer Pipe über einen Socket zu senden, gibt es dann eine andere Null-Kopie-Technik, die ich verwenden kann?
Antwort
Zu viele Anzeigen?Um eine manuelle Nullkopie zu übertragen, müssen Sie sowohl den Socket als auch die Datei im überlappenden Modus öffnen und sie mit einem IO-Abschlussport verbinden. Dann geben Sie einen Lesebefehl für die Datei aus und wenn der Lesevorgang abgeschlossen ist, übergeben Sie den gefüllten Puffer an einen Schreibbefehl für den Socket. Sie können dies wahrscheinlich optimieren, indem Sie die Größe des Sendepuffers am Socket anpassen, um ein Kopieren zu verhindern, und indem Sie die richtigen Flags auswählen, wenn Sie die Datei öffnen.
Beachten Sie, dass Sie wahrscheinlich den anschließenden Socket-Schreibabschluss verwenden sollten, um Ihre Dateien zu lesen. Das heißt, geben Sie nicht ständig neue Lesevorgänge aus, wenn der alte abgeschlossen ist, da der TCP-Stack wahrscheinlich eine Flusskontrolle durchführen wird, weil das TCP-Fenster voll wird, und zu diesem Zeitpunkt werden Sie einen nicht ausgelagerten Pool verbrauchen, da Ihre Socket-Schreibvorgänge immer länger dauern (siehe aquí für weitere Einzelheiten). Legen Sie also die Anzahl der ausstehenden Socket-Schreibvorgänge fest, die Sie pro Verbindung zulassen, und drosseln Sie Ihre Lesevorgänge, wenn diese Anzahl erreicht ist, d.h. schalten Sie von Lesen bei Leseabschluss auf Lesen bei Schreibabschluss um...
Beachten Sie, dass dies nicht so effektiv ist wie die Verwendung von TransmitFile()
selbst, da dies die Übergänge vom Kernel zum Benutzer vermeidet, die auftreten, um Sie über den Abschluss des Lesevorgangs zu informieren und den Schreibaufruf zu tätigen.
Um den ersten Teil Ihrer Frage zu beantworten: Was passiert, wenn Sie es versuchen?