GNU/Linux >> Tutoriels Linux >  >> Linux

Envoyer et recevoir un fichier en programmation socket sous Linux avec C/C++ (GCC/G++)

Faites un man 2 sendfile . Il vous suffit d'ouvrir le fichier source sur le client et le fichier de destination sur le serveur, puis d'appeler sendfile et le noyau hachera et déplacera les données.


La solution la plus portable consiste simplement à lire le fichier en morceaux, puis à écrire les données sur le socket, dans une boucle (et de même, dans l'autre sens lors de la réception du fichier). Vous allouez un buffer, read dans ce tampon, et write de ce tampon dans votre socket (vous pouvez également utiliser send et recv , qui sont des manières spécifiques aux sockets d'écrire et de lire des données). Le contour ressemblerait à ceci :

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;
    }
}

Assurez-vous de lire la documentation pour read et write avec soin, en particulier lors de la manipulation des erreurs. Certains des codes d'erreur signifient que vous devez simplement réessayer, par exemple simplement en boucle avec un continue déclaration, tandis que d'autres signifient que quelque chose est cassé et que vous devez arrêter.

Pour envoyer le fichier à une socket, il y a un appel système, sendfile ça fait exactement ce que tu veux. Il indique au noyau d'envoyer un fichier d'un descripteur de fichier à un autre, puis le noyau peut s'occuper du reste. Il y a une mise en garde que le descripteur de fichier source doit prendre en charge mmap (comme dans, être un fichier réel, pas un socket), et la destination doit être un socket (vous ne pouvez donc pas l'utiliser pour copier des fichiers ou envoyer des données directement d'un socket à un autre) ; il est conçu pour prendre en charge l'utilisation que vous décrivez, consistant à envoyer un fichier à un socket. Cependant, cela n'aide pas à recevoir le fichier; vous auriez besoin de faire la boucle vous-même pour cela. Je ne peux pas vous dire pourquoi il y a un sendfile appel mais pas de recvfile analogue .

Attention, sendfile est spécifique à Linux ; il n'est pas portable sur d'autres systèmes. D'autres systèmes ont souvent leur propre version de sendfile , mais l'interface exacte peut varier (FreeBSD, Mac OS X, Solaris).

Sous Linux 2.6.17, le splice l'appel système a été introduit, et à partir de 2.6.23 est utilisé en interne pour implémenter sendfile . splice est une API plus générale que sendfile . Pour une bonne description de splice et tee , voir la plutôt bonne explication de Linus lui-même. Il souligne comment l'utilisation de splice est fondamentalement comme la boucle ci-dessus, en utilisant read et write , sauf que le tampon est dans le noyau, de sorte que les données n'ont pas à être transférées entre le noyau et l'espace utilisateur, ou peuvent même ne jamais passer par le CPU (appelé "E/S sans copie").


Linux
  1. Rechercher des fichiers et des répertoires sous Linux avec la commande find

  2. Copiez et collez sur la ligne de commande Linux avec xclip

  3. Scénarios Linux en temps réel et problèmes avec leurs solutions

  4. Utilisation de l'entrée-sortie et de la redirection d'erreur sous Linux

  5. Autorisations de fichiers sous Linux avec exemple

Télécharger des fichiers avec Wget sur le shell Linux - Explication et exemples

Commande Linux WC avec exemples

Expliquer Soft Link et Hard Link sous Linux avec des exemples

Comment travailler avec des liens durs et des liens souples sous Linux

commande mailx sous Linux - envoyer et recevoir du courrier Internet

Autorisations et propriété des fichiers Linux expliquées avec des exemples