Bonjour,
J'ai voulu faire une sorte de cp mais réseau.
En local cela fonctionne bien:
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.
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); }
Serveur:
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 #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); }
Quand je lance mon client, lefichier qu'ecrit mon serveur fait 25 mo alors que ma video originale fait plus de 400 mo.
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); }
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?
Partager