GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Senden und Empfangen einer Datei in der Socket-Programmierung unter Linux mit C/C++ (GCC/G++)

Führen Sie einenman 2 sendfile durch . Sie müssen nur die Quelldatei auf dem Client und die Zieldatei auf dem Server öffnen, dann sendfile aufrufen und der Kernel wird die Daten zerhacken und verschieben.


Die portabelste Lösung besteht darin, die Datei nur in Blöcken zu lesen und die Daten dann in einer Schleife in den Socket zu schreiben (und umgekehrt beim Empfang der Datei). Sie weisen einen Puffer zu, read in diesen Puffer und write aus diesem Puffer in Ihren Socket (Sie könnten auch send verwenden und recv , die Socket-spezifische Methoden zum Schreiben und Lesen von Daten sind). Die Gliederung würde in etwa so aussehen:

while (1) {
    // Read data into buffer.  We may not have enough to fill up buffer, so we
    // store how many bytes were actually read in bytes_read.
    int bytes_read = read(input_file, buffer, sizeof(buffer));
    if (bytes_read == 0) // We're done reading from the file
        break;
    
    if (bytes_read < 0) {
        // handle errors
    }
    
    // You need a loop for the write, because not all of the data may be written
    // in one call; write will return how many bytes were written. p keeps
    // track of where in the buffer we are, while we decrement bytes_read
    // to keep track of how many bytes are left to write.
    void *p = buffer;
    while (bytes_read > 0) {
        int bytes_written = write(output_socket, p, bytes_read);
        if (bytes_written <= 0) {
            // handle errors
        }
        bytes_read -= bytes_written;
        p += bytes_written;
    }
}

Lesen Sie unbedingt die Dokumentation für read und write sorgfältig, insbesondere im Umgang mit Fehlern. Einige der Fehlercodes bedeuten, dass Sie es einfach noch einmal versuchen sollten, zum Beispiel einfach eine Wiederholung mit einem continue ausführen Aussage, während andere meinen, dass etwas kaputt ist und Sie aufhören müssen.

Um die Datei an einen Socket zu senden, gibt es einen Systemaufruf sendfile das macht genau das was du willst. Es weist den Kernel an, eine Datei von einem Dateideskriptor zu einem anderen zu senden, und dann kann sich der Kernel um den Rest kümmern. Es gibt eine Einschränkung, dass der Deskriptor der Quelldatei mmap unterstützen muss (wie in, eine tatsächliche Datei sein, kein Socket), und das Ziel muss ein Socket sein (Sie können es also nicht verwenden, um Dateien zu kopieren oder Daten direkt von einem Socket zu einem anderen zu senden); Es wurde entwickelt, um die von Ihnen beschriebene Verwendung zu unterstützen, eine Datei an einen Socket zu senden. Es hilft jedoch nicht beim Empfangen der Datei; Dafür müsstest du die Schleife selbst machen. Ich kann Ihnen nicht sagen, warum es einen sendfile gibt anrufen, aber kein analoges recvfile .

Achtung sendfile ist Linux-spezifisch; es ist nicht auf andere Systeme übertragbar. Andere Systeme haben häufig ihre eigene Version von sendfile , aber die genaue Schnittstelle kann variieren (FreeBSD, Mac OS X, Solaris).

In Linux 2.6.17 ist der splice Systemaufruf wurde eingeführt und wird ab 2.6.23 intern verwendet, um sendfile zu implementieren . splice ist eine allgemeinere API als sendfile . Für eine gute Beschreibung von splice und tee , siehe die ziemlich gute Erklärung von Linus selbst. Er weist darauf hin, wie man splice verwendet ist im Grunde genau wie die Schleife oben, mit read und write , außer dass sich der Puffer im Kernel befindet, sodass die Daten nicht zwischen dem Kernel und dem Benutzerbereich übertragen werden müssen oder möglicherweise nicht einmal die CPU passieren (bekannt als "Zero-Copy-I/O").


Linux
  1. Finden Sie Dateien und Verzeichnisse unter Linux mit dem Befehl find

  2. Kopieren und Einfügen in der Linux-Befehlszeile mit xclip

  3. Linux-Echtzeitszenarien und Probleme mit ihren Lösungen

  4. Dateiberechtigungen unter Linux mit Beispiel

  5. C++ neue Operator-Thread-Sicherheit in Linux und gcc 4

Herunterladen von Dateien mit Wget auf der Linux-Shell - Erklärung und Beispiele

Linux-WC-Befehl mit Beispielen

Erläuterung von Soft Link und Hard Link in Linux anhand von Beispielen

Wie man mit Hardlinks und Softlinks unter Linux arbeitet

mailx-Befehl unter Linux – Internet-Mail senden und empfangen

Linux-Dateiberechtigungen und Eigentumsrechte mit Beispielen erklärt