2010-12-08 29 views
0

J'ai reçu une tâche à l'école pour écrire un programme FTP en langage C (pour Linux). J'ai toutes les fonctionnalités de base en un rien de temps (ls, cd), mais j'ai des problèmes avec la partie transfert de fichiers. J'utilise sendfile pour envoyer le fichier sur le socket comme celui-ci:Envoyer un fichier via une socket en C

int fd = open(temp, O_RDONLY); 
int rc = sendfile (client_fd, fd, &offset, statbuf.st_size); 

Je ne peux pas sembler comprendre comment recevoir ce fichier sur le côté client. Je l'ai essayé comme pour le débogage:

while((i = read(sock, message, MSG_LEN - 1)) > 0) { 

    message[i] = '\0'; 
    printf("%s", message); 
} 

Cela fait un bon travail à l'impression des fichiers texte, mais si je tente d'envoyer des fichiers binaires, par exemple, il suffit d'imprimer le début du fichier binaire et se bloque à la partie read() (puisque rien ne vient du serveur, je pense).

J'apprécie toutes les suggestions!

+0

Peut-être essayer à nouveau sendfile, avec le descripteur de socket étant l'entrée et un fichier ouvert pour l'écriture en sortie ...? –

+2

Les fichiers BTW/binaires peuvent contenir 0 octet que les fonctions de type C comme printf peuvent confondre avec les terminaisons ASCIIZ NUL, ainsi que d'autres valeurs correspondant aux codes de contrôle ASCII pour effacer l'écran, déplacer le curseur, etc. contenu octet par octet en hexadécimal ou utiliser d'une autre manière pour le rendre lisible par l'homme et compatible terminal. –

+0

Ou utilisez fwrite (message, 1, i, stdout) et redirigez la sortie de votre programme vers un fichier à partir du shell –

Répondre

2

Vous devez arrêter le côté écriture de la prise après l'envoi du fichier, de sorte que le récepteur connaît la fin du fichier a été atteint:

shutdown(client_fd, SHUT_WR); 

(shutdown() est utilisé au lieu de close(), de sorte que vous pouvez savoir si l'autre côté a bien reçu le fichier entier ou non).

Votre côté de lecture verra alors la fin du fichier (read() retournant 0), à quel point il devrait close() sa fin du socket. Le serveur verra alors la fin du fichier, et il peut également fermer son socket (et enregistrer un transfert réussi).

+0

Cela n'a pas vraiment aidé, il transfère encore des fichiers comme je l'ai décrit dans le premier post, mais maintenant si j'essaye de donner d'autres commandes après 'get', j'obtiens une erreur en disant 'broken pipe'. – ehehhh

+0

J'ai cherché autour et trouvé que certains suggèrent d'utiliser recv(). Voudriez-vous suggérer read() ou recv()? – ehehhh

+0

Merci pour votre réponse et à vous autres pour les suggestions! Le problème était que j'ai essayé de fork() mon programme avant d'envoyer le fichier, apparemment je ne l'ai pas fait correctement, donc ça a tout chamboulé. Ça fonctionne maintenant. – ehehhh