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?