salut j'ai le même travail qu'ici à rendre demain mais j'arrive pas à afficher le résultat après l'exécution dans le screen de client, je veux bien votre aide svp et merci bien.
salut j'ai le même travail qu'ici à rendre demain mais j'arrive pas à afficher le résultat après l'exécution dans le screen de client, je veux bien votre aide svp et merci bien.
Alors pour l'execution de la commande, les fonctions de la famille execv, a lancer dans un autre processus pour eviter de quitter le programme avec fork. Pour recuperer le path du binaire de la commande, tu peux le recuperer en parsant le PATH de l'environnement qu'on peut obtenir grace a la fonction getenv. Pour envoyer directement le retour de la commande, les fonctions de la famille dup le feront.
Je crois pas avoir oublie de truc...
pour moi le problem que l'execution de la commande shell (par exp ls) se fait dans le coté serveur et nn pas au coté client
Quel est le probleme ? Qu'est-ce qui t'empeche d'executer la commande sur le serveur ?
je peux vous montre mon prg (client et serveur) ?
Ba euh oui, ce forum est la pour ca... N'oublie pas d'utiliser les balises code.
Merci bien
client.c
serveur.c
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 #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <netdb.h> #include <string.h> #include <stdlib.h> #define TAILLE_TAMPON 1000 static int fd; void ErreurFatale(char message[]) { printf("CLIENT> Erreur fatale\n"); perror(message); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { struct sockaddr_in adresse_socket_serveur; //connexion au serveur// struct hostent *hote; int taille_adresse_socket_serveur; char *nom_serveur; int numero_port_serveur; char *requete, reponse[TAILLE_TAMPON]; int longueur_requete, longueur_reponse; /* 1. récéption des parametres de la ligne de commande */ if (argc != 4) { printf("Usage: %s hote port message\n", argv[0]); exit(EXIT_FAILURE); }; nom_serveur = argv[1]; numero_port_serveur = atoi(argv[2]); requete = argv[3]; /* 2. Initialisation du socket */ /* 2.1 création du socket en mode datagramme */ fd = socket(AF_INET, SOCK_DGRAM, 0);//socket udp// if (fd < 0) ErreurFatale("Creation socket"); /* 2.2 recherche de la machine serveur */ hote = gethostbyname(nom_serveur);//pour obtenir des informations sur le réseau, renvoie un pointeur vers la structure hostent , ou bien un pointeur NULL si une erreur se produit// if (hote == NULL) ErreurFatale("Recherche serveur"); /* 2.3 Remplissage adresse serveur */ adresse_socket_serveur.sin_family = AF_INET; adresse_socket_serveur.sin_port = htons(numero_port_serveur); adresse_socket_serveur.sin_addr = *(struct in_addr *) hote->h_addr; taille_adresse_socket_serveur = sizeof adresse_socket_serveur; longueur_requete = strlen(requete) + 1; /* 3. Envoi de la requete */ printf("REQUETE> %s\n", requete); if (sendto(fd, requete, longueur_requete, 0, /* flags */ (struct sockaddr *) &adresse_socket_serveur, taille_adresse_socket_serveur) < 0) ErreurFatale("Envoi requete"); /* 4. Lecture de la réponse */ longueur_reponse = recvfrom(fd, reponse, TAILLE_TAMPON, 0, NULL, 0); if (longueur_reponse < 0) ErreurFatale("Attente réponse"); printf("REPONSE> %s\n", reponse); close(fd); printf("CLIENT> Fin.\n"); exit(0); }
pour moi je ne précise pas que la cmd 'ls' mais n'importe quelle cmd shell
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 #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <arpa/inet.h> #include <ctype.h> #define TAILLE_TAMPON 1000 static int fd, fd2; void ErreurFatale(char message[]) { printf("SERVEUR> Erreur fatale\n"); perror(message); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { struct sockaddr_in adresse_serveur; size_t taille_adresse_serveur; int numero_port_serveur; /* 1. réception des paramétres de la ligne de commande */ if (argc != 2) { printf("usage: %s port\n", argv[0]); exit(1); }; numero_port_serveur = atoi(argv[1]); /* 2. Initialisation du socket de r?ception */ /* 2.1 Création du socket en mode non-connect? (datagrammes) */ fd = socket(AF_INET, SOCK_DGRAM, 0);//udp socket// if (fd < 0) ErreurFatale("socket"); /* 2.2 Remplissage de l'adresse de réception (protocole Internet TCP-IP, réception acceptée sur toutes les adresses IP du serveur, numero de port indiqué) */ adresse_serveur.sin_family = AF_INET;/*famille adresse internet*/ adresse_serveur.sin_addr.s_addr = INADDR_ANY;/*l'adresse ip de l'hote (0.0.0.0)*/ adresse_serveur.sin_port = htons(numero_port_serveur);/*port dans l'octet réseau*/ /* 2.3 Association du socket au port de réception */ taille_adresse_serveur = sizeof adresse_serveur; if (bind(fd, (struct sockaddr *) &adresse_serveur,///bind affecte l'adresse indiquée Ã* la socket*// taille_adresse_serveur) < 0) ErreurFatale("bind"); printf("SERVEUR> Le serveur ?coute le port %d\n", numero_port_serveur); while (1) { struct sockaddr_in adresse_client; int taille_adresse_client; char tampon_requete[TAILLE_TAMPON], tampon_reponse[TAILLE_TAMPON]; int lg_requete, lg_reponse; int newout; /* 3. Attente d'un datagramme (requete) */ taille_adresse_client = sizeof(adresse_client); lg_requete = recvfrom(fd, tampon_requete, TAILLE_TAMPON, 0, /* flags,recvfrom utilisé pour le monde non connécté */ (struct sockaddr *) &adresse_client, (socklen_t *) &//*socklen_t, qui est un type intégral opaque non signé de longueur d'au moins 32 bits. Pour prévenir les problèmes de portabilité, il est recommandé que les demandes ne devraient pas utiliser des valeurs supérieures Ã* 2 ^ 32 - 1*// taille_adresse_client); if (lg_requete < 0) ErreurFatale("recfrom"); /* 4. Affichage message avec sa provenance et sa longueur */ printf("%s:%d [%d]\t: %s\n",//*convertit l'adresse Internet de l'hôte in donne dans l'ordre des octets du réseau en une chaîne de caractères dans la notation numérique pointée. La chaîne est renvoyée dans un tampon alloué statiquement, qui est donc écrasé Ã* chaque appel*// inet_ntoa(adresse_client.sin_addr), ntohs(adresse_client.sin_port),//*convertit un entier court depuis l'ordre des octets du réseau vers celui de l'hôte// lg_requete, tampon_requete); system(tampon_requete); /* 5. Envoi de la r?ponse */ //*en mode non connécté*// if (sendto(fd2, tampon_reponse, lg_reponse, 0, (struct sockaddr *) &adresse_client, taille_adresse_client) < 0); }; }
pour l'exécution de serveur :
et pour le client :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2gcc server.c .a/.out server 1024
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 gcc client.c .a/.out client localhost 1024 " la commande "
Et bien une fois que tu as recu ta chaine de caractere, tu la parses et tu fais tout ce que j'ai dit dans mon precedent post. En gros :
-> recu : ls -l popo.c
-> parsing :
cmd[0] = ls
cmd[1] = -l
cmd[2] = popo.c
-> on trouve le path de ls :
cmd[0] = /bin/ls (par exemple)
-> on cree un fork, on pipe et on lance la commande avec execv.
Tu peux te faciliter la vie en passant directement la chaine de caractere recue (a savoir "ls -l popo.c") a bash (ou tcsh, ou zsh, ou ...) en n'oubliant pas de forker et de creer un pipe redirige sur ta socket.
PS: pourquoi utiliser l'UDP pour l'affichage de la commande ? C'est pas tres malin comme idee...
merci bien pour votre aide, et pour l'utilisation de udp c'est juste pcq j'ai trouvé que cette sol ,car c'est la premiére fois que je fais du programmation avec les sockets
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager