Bonjour,
J'ai un petit projet a faire en programmation réseau. Je suis novice dans cette matière et je n'ai eu que 3 TP très encadrés donc c'est assez flou pour moi, malgré le cours.
Le but de mon projet est de réaliser un mini client/serveur ftp.
Le mini client se connecte au serveur sur le port n, affiche la bannière d'accueil. Il lit les commandes saisies au clavier par l'utilisateur et les envoie au miniserveur. Il affiche les reponses du mini serveur depuis le port n et les affiche à l'écran.
Il utilise le port n+1 du mini serveur pour le transfert de fichier.
Dans le cahier des charges, le mini serveur ftp doit implémenter la fonction" GET filename" qui lit le contenu du fichier "filename" envoyé par le miniclient et le sauvegarde dans le repertoire courant.
Sa réponse sera: "226 Transfert complete".
Ce que j'ai fait n'est qu'un brouillon et ne fonctionne pas du tout. C'est juste pour savoir si je ne faisais pas fausse route concernant la gestion serveur/client et la gestion des ports (l'un pour les reponses, l'autres pour les transferts). J'ai essaye de commenter un maximum mon code.
Je sais pas si on doit faire 2 sockets pour gerer les deux ports ou si tout se joue sur le bind qui va lier la socket a un port désiré.
pour le 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 #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> main(argc,argv) int argc ; char *argv[] ; { int sd1,sd2; struct sockaddr_in sa1; /* Structure Internet sockaddr_in */ struct hostent *hptr ; /* Infos sur le serveur */ char *serveur ; /* Nom du serveur distant */ char c; char buf[256]; /* Buffer */ int n, i; struct sockaddr_in sa2; int port,port1; /* verification du nombre d'arguments de la ligne de commande */ if (argc != 3) { printf("ftpclient. Erreur d'arguments\n"); printf("Syntaxe : %% ftpclient nom_de_la_machine numéro_de_port\n"); exit(1); } /* Recuperation nom du serveur et du numéro de port */ serveur = argv[1]; port = atoi(argv[2]); port1 = atoi(argv[2])+1; /* Recuperation des infos sur le serveur dans /etc/hosts pour par DNS */ if((hptr = gethostbyname(serveur)) == NULL) { printf("Probleme de recuperation d'infos sur le serveur\n"); exit(1); } /* Initialisation la structure sockaddr sa avec les infos formattees : */ /* bcopy(void *source, void *destination, size_t taille); */ bcopy((char *)hptr->h_addr, (char*)&sa1.sin_addr, hptr->h_length); bcopy((char *)hptr->h_addr, (char*)&sa2.sin_addr, hptr->h_length); /* Famille d'adresse : AF_INET = PF_INET */ sa1.sin_family = AF_INET; sa2.sin_family = AF_INET; /* Initialisation du numero du port */ sa1.sin_port = htons(port); sa2.sin_port = htons(port1); /* Creation de la socket TCP pour les echange reponses */ if((sd1 = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("Probleme lors de la creation de socket\n"); exit(1); } /* Creation de la socket TCP pour le transfert de fichier */ if((sd2 = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("Probleme lors de la creation de socket\n"); exit(1); } /* Etablissement de la connexion avec le serveur ftp sur le port reservé aux demandes/ réponses*/ if((connect(sd1, (struct sockaddr *) &sa1, sizeof(sa1))) < 0 ) { printf("Probleme de connexion avec le serveur\n"); exit(1); } /* Lecture de la banniere d'accueil du serveur ftp */ n = read(sd, buf, sizeof(buf)); /* Ecriture sur stdout de la bannière d'accueil */ write(1, buf, n); /*traitement des commandes/réponses */ while(strncmp(buf, "QUIT",4)) { n=read(0,buf,sizeof(buf)); write(sd,buf,n); if (!strncmp(buf,"GET",3)) // get_file(filename) fonction qui va permettre le transfert de fichier n = read(sd, buf, sizeof(buf)); write(1, buf, n); } /* Fermeture de la socket */ close(sd); printf("221 Goodbye \n"); exit(0); } void get_file(char * filename) { /*connexion avec le serveur sur le port réservé aux transferts de fichiers */ if((connect(sd2, (struct sockaddr *) &sa2, sizeof(sa2))) < 0 ) { printf("Probleme de connexion avec le serveur\n"); exit(1); /* A COMPLETER POUR LA RECUPERATION DU FICHIER ENVOYE PAR LE SERVEUR */ }
Pour le serveur:
Merci pour vos commentaires.
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> main(argc,argv) int argc ; char *argv[] ; { int sd1,sd2; struct sockaddr_in sa1,sa2; /* Structure Internet sockaddr_in */ struct hostent *hptr ; /* Infos sur le serveur */ int port; /* Numero de port du serveur */ int newsd1,newsd2; /* Id de la socket entrante */ struct sockaddr_in newsa1,newsa2; /* sockaddr_in de la connection entrante */ int newsalength1,newsalength2; struct hostent *newhptr; /* Infos sur le client suivant /etc/hosts */ int i,n; char buf[256]; /* Buffer */ char accueil[]="220 ftpserveur ready \n"; /* Bannière d'accueil du serveur */ char erreur[]="500 syntax erro, command unrecognized\n"; char fin[]="226 Transfert complete\n"; char err[]="550 Action not taken \n"; /* verification du nombre d'arguments de la ligne de commande */ if (argc != 2) { printf("ftpserveur. Erreur d'arguments\n"); printf("Syntaxe : %% ftpserveur numero_port\n"); exit(1); } /* Recuperation numero port passe en argument */ port = atoi(argv[1]); port1 = atoi(argv[1])+1 /* Initialisation la structure sockaddr sa avec les infos formattees : */ /* Famille d'adresse : AF_INET = PF_INET */ sa1.sin_family = AF_INET; sa2.sin_family = AF_INET; /* Initialisation du numero du port */ sa1.sin_port = htons(port); sa1.sin_addr.s_addr = INADDR_ANY; sa2.sin_port = htons(port1); /* Creation de la socket TCP pour l'echange des fichier et celle pour les reponses/demandes */ if((sd1 = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("Probleme lors de la creation de socket\n"); exit(1); } if((sd2 = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("Probleme lors de la creation de socket\n"); exit(1); } /* Bind sur la socket pour les lier a leur port respectif*/ if(bind(sd1, (struct sockaddr *) &sa1, sizeof(sa1)) == -1) { printf("Probleme avec le bind\n"); exit(1); } if(bind(sd2, (struct sockaddr *) &sa2, sizeof(sa2)) == -1) { printf("Probleme avec le bind\n"); exit(1); } /* Initialisation de la queue d'ecoute des requetes (5 max) */ listen(sd, 5); printf("220 ftpserveur ready \n"); i = 0; while(1) { /* Ne pas oublier : newsalength contient la taille de la structure sa attendue */ newsalength1 = sizeof(newsa1) ; if((newsd1 = accept(sd1, ( struct sockaddr * ) &newsa1, &newsalength)) < 0 ) { printf("Erreur sur accept\n"); exit(1); } /* Compteur nombre connexions */ i++; /* nom du client */ printf("Connection No %d sur le port %d...\n", i, ntohs(newsa.sin_port)); /* Envoie banniere d'accueil */ write(newsd,accueil, sizeof(accueil)); /*traitement commande/reponse */ while(strncmp(buf, "QUIT",4)) { n=read(newsd, buf, sizeof(buf)); if (!strncmp(buf, "GET", 3)) a=get_file(filename); if a write(newsd1, fin, sizeof(fin)); else write(newsd1, err, sizeof(fin)); } close(newsd1); } /* Fermeture du serveur. Never reached*/ close(sd1); printf("221 Goodbye \n"); exit(0); } int get_file(char* filename) { newsalength2 = sizeof(newsa2) ; if((newsd2 = accept(sd2, ( struct sockaddr * ) &newsa2, &newsalength2)) < 0 ) { printf("Erreur sur accept\n"); exit(1); } if ((FILE*fp=fopen(filename,"r"))==NULL) // ouvert du fichier dont le nom est passé en argument { return 0; } while(fgets(line,240,fp)) { write(newsd,line,strlen(line)); } write(newsd,fin,sizeof(fin)); return 1; close(newsd2); }
Partager