IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Envoi de fichiers avec read et write


Sujet :

Réseau C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 42
    Points : 29
    Points
    29
    Par défaut Envoi de fichiers avec read et write
    Bonjour,

    J'ai voulu faire une sorte de cp mais réseau.
    En local cela fonctionne bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #include <fcntl.h> 
     
    #include <unistd.h> 
     
    #include <stdlib.h> 
     
    #include <stdio.h> 
     
    int main(int n_args,char *args[])
    	{ 
    	int BUF_SIZE=4096,lu,ecrit,desc_source,desc_cible; 
    	char buffer[BUF_SIZE]; 
     
    	if (n_args!=3) 
    		{
    		write(STDERR_FILENO,"2 parametres\n",13);
    		exit(2);
    		} 
     
    	desc_source=open(args[1],O_RDONLY); 
    	if (desc_source < 0)
    		{
    		perror("erreur d'ouverture de la source");
    		exit(2);
    		} 
     
    	desc_cible=open(args[2],O_WRONLY | O_CREAT,0700); 
    	if (desc_cible < 0)
    		{
    		perror("erreur d'ouverture de la cible");
    		exit(2);
    		} 
    	do
    		{ 
    		lu=read(desc_source,buffer,BUF_SIZE); 
    		if (lu<0) 
    			{
    			perror("Erreur de lecture");
    			exit(2);
    			} 
    		ecrit=write(desc_cible,buffer,lu); 
    		if (ecrit<0) 
    			{
    			perror("Erreur d'écriture");
    			exit(2);
    			} 
    		}
    	while(lu!=0); 
    	close(desc_cible); 
    	close(desc_source); 
    	return(0); 
    }
    J'ai pensé qu'avec une socket, le principe est le même sauf que le client fais le write dans la socket et le serveur le write dans le fichier cible.

    Serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    #include <stdio.h>
     
    #include <sys/socket.h>
     
    #include <netinet/in.h>
     
    #include <string.h>
     
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <time.h>
    #include <fcntl.h> 
     
    #include <unistd.h> 
    #include <dirent.h>
     
     
    #define	MAXLINE		4096	/* max text line length */
    #define	BUFFSIZE	8192	/* buffer size for reads and writes */
     
    /* Following shortens all the typecasts of pointer arguments: */
    #define	SA	struct sockaddr
     
    int
    main(int argc, char **argv)
    {
    	int					listenfd, connfd, n, fic, i=0;
    	struct sockaddr_in	servaddr, cliaddr;
    	socklen_t			len;
    	char				buff[MAXLINE+1], recvline[MAXLINE +1];
     
     
    	listenfd = socket(AF_INET, SOCK_STREAM, 0);
     
    	bzero(&servaddr, sizeof(servaddr));
    	servaddr.sin_family      = AF_INET;
    	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    	servaddr.sin_port        = htons(35000);	
     
    	bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
     
    	listen(listenfd, 10);
    	printf("ecoute sur le port 35000 ...\n\n");
    fic=open("copie.mkv",O_WRONLY | O_CREAT,0700); 				
    		len=sizeof(cliaddr);
    		connfd = accept(listenfd, (SA *)&cliaddr, &len);
    		printf("conexion de %s sur le port source %d\n",inet_ntop(AF_INET,&cliaddr.sin_addr,buff,sizeof(buff)),ntohs(cliaddr.sin_port));
     
    		do {
    			if ( (n = read(connfd, recvline, MAXLINE)) > 0) {
     
            		write(fic, recvline, strlen(recvline));  
            		snprintf(buff, MAXLINE, "continue");
            		i++;printf("%d: lu %d, continue..\n",i,n );
    				write(connfd, buff, MAXLINE);
           		}
           	}
           	while (n!=19);
           	close(fic);
    		snprintf(buff, MAXLINE, "fichier recu");		
    		write(connfd, buff, MAXLINE);
    		printf("termine!\n");
    		close(connfd);
    }
    Client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
     
    #include <stdlib.h>
     
    #include <stdio.h>
     
    #include <string.h>
     
    #include <fcntl.h> 
     
    #include <unistd.h> 
    #include <sys/socket.h>
     
    #include <netinet/in.h>
     
    #include <arpa/inet.h>
     
    #define	MAXLINE		4096	/* max text line length */
    #define	BUFFSIZE	8192	/* buffer size for reads and writes */
     
    /* Following shortens all the typecasts of pointer arguments: */
    #define	SA	struct sockaddr
     
     
     int main(int argc, char **argv)
    {
     int sockfd,nb,fic,lu, ecrit;
     char var1[200];
     char  buff[MAXLINE],  recvline[MAXLINE + 1], recvline2[MAXLINE + 1];
     
     fic=open("video.mkv",O_RDONLY); 
     struct sockaddr_in servaddr;
     
     
     if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
     
            printf("socket error");
     
     
     
        bzero(&servaddr, sizeof(servaddr));
     
        servaddr.sin_family = AF_INET;
     
        servaddr.sin_port = htons(35000);  /* daytime server */
     
        if (inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0)
     
        	printf("inet_pton error for 127.0.0.1");
     
     
     
        if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) {
        	perror("Impossible de se connecter au serveur!");
        	exit(0);
        }
    	if (fic < 0)
     
    		{
     
    		perror("erreur d'ouverture de la source");
     
    		exit(2);
     
    		}
     do
     
    		{ 
     
    		lu=read(fic,buff,MAXLINE); 
     
    		if (lu<0) 
     
    			{
     
    			perror("Erreur de lecture");
     
    			exit(2);
     
    			}
    		nb++;printf("%d lu : %d \n",nb,lu);	 
     
     
    		if (lu>0) {
    			ecrit=write(sockfd,buff,lu); 
     
    			if (ecrit<0) 
     
    				{
     
    				perror("Erreur d'écriture");
     
    				exit(2);
     
    			} 
    			if ( (lu = read(sockfd, recvline, MAXLINE)) > 0) {
     
            		recvline[lu] = 0;        /* null terminate */
           			printf("reçu:%s\n",recvline);  
      			}
      		}
     
    }		
     
    	while(lu!=0); 
    	close(fic);
    	snprintf(buff, sizeof(buff),"##!fin du fichier.$");
    	printf("envoi de fin de fichier\n");
    	write(sockfd,buff,strlen(buff)); 	
    	printf("le fichier a ete lu %d fois\n",nb);
       if ( (lu = read(sockfd, recvline, MAXLINE)) > 0) {
     
            		recvline[lu] = 0;        /* null terminate */
           printf("reçu:%s\n",recvline);  
       }
     
        return(EXIT_SUCCESS);
     
    }
    Quand je lance mon client, lefichier qu'ecrit mon serveur fait 25 mo alors que ma video originale fait plus de 400 mo.
    Pourtant il recoit bien le même nombre d'informations que le serveur lui envoi, c'est bizar.
    Par contre sur des petits fichiers cela semble passer.

    Pourquoi ce decalage?

    Et comment gérer la fin de fichier parceque là c'est un peu foireux, je teste la taille de ce que j'ai reçu, mais si les dernieres donnees du fichier font cette taille, ça marche plus.

    J'ai pensé envoyé une premiere fois le nombre de données que le serveur doit lire, mais ca implique un temps double, y aurait-il un moyen plus simple?

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Z-fly Voir le message
    J'ai pensé envoyé une premiere fois le nombre de données que le serveur doit lire
    C'est la bonne méthode

    Citation Envoyé par Z-fly Voir le message
    mais ca implique un temps double
    Pourquoi cela ?
    Tu récupères la taille du fichier (par le fonction stat() ou équivalent par exemple), tu envoies cette taille et ensuite tu envoies le fichier dans une boucle de lecture.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 42
    Points : 29
    Points
    29
    Par défaut
    oui cela fonctionne bien, je pensais pas que l'on pouvait connaitre la taille d'un fichier avec une fonction sans avoir à parcourir tout le fichier.

    Merci bien

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Z-fly Voir le message
    oui cela fonctionne bien, je pensais pas que l'on pouvait connaitre la taille d'un fichier avec une fonction sans avoir à parcourir tout le fichier.
    fseek()/ftell()

    Au fait, je recommande de rester le plus standard possible :

    - fopen(), fclose, fread(), fwrite(), fgets(), fprintf()
    - recv(), send()

    Et attention, strlen() ne fonctionne que sur les chaines bien formées. En mode binaire, ça ne fonctionne évidemment pas. Idem en réception. Placer un 0 dans le buffer n'a aucun sens en binaire...

    Emission (code minimum) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int n;
    unsigned char buf[1024];
    while ((n = fread (buf, sizeof buf, 1, fp)) > 0)
    {
       send (sock, buf, sizeof buf, 0);
    }
    fclose (fp);
    Réception :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int n;
    unsigned char buf[1024];
    while ((n = recv (buf, sizeof buf, sock)) > 0)
    {
       fwrite (buf, sizeof buf, 1, fp);
    }
    fclose(fp);
    closesocket(sock);
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Au fait, je recommande de rester le plus standard possible :

    - fopen(), fclose, fread(), fwrite(), fgets(), fprintf()
    - recv(), send()
    +1

    Pour les entrées/sorties, je préfère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    > send (sock, buf, n, 0);
    > et
    > fwrite (buf, n, 1, fp);
    En supposant que n soit toujours inférieur ou égal à sizeof buf.

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Melem Voir le message
    Pour les entrées/sorties, je préfère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    > send (sock, buf, n, 0);
    > et
    > fwrite (buf, n, 1, fp);
    En supposant que n soit toujours inférieur ou égal à sizeof buf.
    Comment pourrait il en être autrement dans le code que j'ai présenté ?
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 42
    Points : 29
    Points
    29
    Par défaut
    Oui j'avais effectivement lu qu'il était plutôt conseillé d'utiliser send/ recv eu lieu du couple read/write dans le cas des sockets, ou fread/ fwrite pour les fichiers.

    J'ai remplacé tout mes read et write.
    J'ai testé quand même sait-on jamais, ça fonctionne toujours bien

    Tient dailleurs juste par curiosité vu qu'un read fonctionne pour un descripteur de fichier ou de socket, le recv fonctionne aussi sur un fichier ?

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Z-fly Voir le message
    Tient dailleurs juste par curiosité vu qu'un read fonctionne pour un descripteur de fichier ou de socket, le recv fonctionne aussi sur un fichier ?
    Cette question n'a aucun sens. recv() c'est pour un flux réseau.
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 42
    Points : 29
    Points
    29
    Par défaut
    Je sais bien, ça ne m'est pas venu à l'esprit de faire un recv sur un fichier lol

  10. #10
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par Melem
    Pour les entrées/sorties, je préfère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    > send (sock, buf, n, 0);
    > et
    > fwrite (buf, n, 1, fp);
    En supposant que n soit toujours inférieur ou égal à sizeof buf.
    Comment pourrait il en être autrement dans le code que j'ai présenté ?
    . Je n'avais que mon code sous les yeux (sans savoir d'où il est tombé ) alors j'ai écrit cela par simple réflexe .

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Pb avec read et write sous vc++
    Par Jbx 2.0b dans le forum SDL
    Réponses: 13
    Dernier message: 28/04/2006, 14h58
  2. Réponses: 7
    Dernier message: 27/04/2006, 16h51
  3. [VB]Envoie de fichier avec winsock
    Par Xdrei dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 24/03/2006, 09h54
  4. envoie de fichier avec winsock2
    Par chichou10 dans le forum Bibliothèques
    Réponses: 8
    Dernier message: 08/03/2006, 00h38
  5. Envoi de fichier avec Indy
    Par Nicodemus dans le forum Web & réseau
    Réponses: 2
    Dernier message: 28/10/2005, 15h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo