[langage C] Problème client/serveur
Fermé
legyptien
Messages postés
382
Date d'inscription
lundi 19 novembre 2007
Statut
Membre
Dernière intervention
23 avril 2022
-
21 déc. 2007 à 02:08
djessika - 28 oct. 2008 à 12:57
djessika - 28 oct. 2008 à 12:57
A voir également:
- [langage C] Problème client/serveur
- Impossible d'atteindre le serveur dhcp - Forum Réseau
- Changer serveur dns - Guide
- Orange service client - Guide
- Formate pour taxer client frigo vide - Forum PDF
- Filezilla client ou serveur ✓ - Forum Réseau
9 réponses
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
21 déc. 2007 à 08:40
21 déc. 2007 à 08:40
l'adresse IP du client est contenu dans la structure sockaddr qui est passé lors du accept. c'est le membre sin_addr.
Donc, il suffit de passer cette structure à str_echo().
ensuite, tu récupère la chaine de caractère avec char* inet_ntoa((sockaddr_in).sin_addr) que tu n'a plut qu'a concaténer dans ton s.
Et voilà ! l'adresse TCP, je ne sais pas ce que c'est;
Donc, il suffit de passer cette structure à str_echo().
ensuite, tu récupère la chaine de caractère avec char* inet_ntoa((sockaddr_in).sin_addr) que tu n'a plut qu'a concaténer dans ton s.
Et voilà ! l'adresse TCP, je ne sais pas ce que c'est;
legyptien
Messages postés
382
Date d'inscription
lundi 19 novembre 2007
Statut
Membre
Dernière intervention
23 avril 2022
9
21 déc. 2007 à 11:20
21 déc. 2007 à 11:20
ok merci a toi char snipeur.
legyptien
Messages postés
382
Date d'inscription
lundi 19 novembre 2007
Statut
Membre
Dernière intervention
23 avril 2022
9
1 janv. 2008 à 21:14
1 janv. 2008 à 21:14
en fait, apres avoir bien etudié le code, j ai encore des questions (toutes pour le programme echo_server):
Dans le programme "echoserveur", je dois faire inet_ntoa(cli_addr.sin_addr) juste apres le "accept" et le resultat renvoyé sera l adresse IP du client sous le bon format si j'ai bien compris. Mais je peux aussi utiliser la fonction getpeername:
int getpeername(int s, struct sockaddr *name, socklen_t *namelen) qui est cencé renvoyer l adresse IP et le port TCP correspondant a la socket s.
1) quel est la difference entre gatpeername et inet_ntoa puisque les 2 nous donne l adresse IP (à part le fait que le getpeername renvoi aussi le port TCP)
2) Dans toutes les documentations on voit " int getpeername(...) " , comment il peut renvoyer 2 choses, il faut une structure pour ca.C'est le int que je comprends pas.
en definitive, ces 2 questions montrent que j ai pas bien compris l'utilité ET la maniere de me servir de getpeername.
3)Supposons que tout se passe bien jusqu au :
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
fprintf(stderr, "Error in server: can't bind local address\n");
return(0);
}
et que le bind se passe mal pour une raison quelconque, on va "imprimer" error in server et quitter le programme mais le socket qui etait ouvert depuis tout a l heure restera ouvert ? donc il faudrait avant le return "close(socket", qu est ce que vous en pensez? Et ce serait pareil pour un peu plus loin si le accept se passe mal , il faut faire un close??
4)D apres ce que j ai compris "newsockfd" est là pour chaque client. et des qu on a fait "str_echo(newsockfd)" on ferme newsockfd.Ca ok.Mais sockfd est le socket chargé de la connexion, on devrait fermer ce socket à un moment donné? si la reponse est "non" alors ma ligne close(sockfd) ne sert à rien. Si la reponse est oui alors il y a un probleme parce que quand je regarde mon programme, on sort jamais du for(;;) donc on fait jamais close(sockfd)!!!!
En resumé le getpeername et les fermetures de sockets sont pas super clair à mes yeux. Apres ca je pense que j'aurai plus de question.
je vous remercie d avance de m'avoir lu jusqu au bout.
Dans le programme "echoserveur", je dois faire inet_ntoa(cli_addr.sin_addr) juste apres le "accept" et le resultat renvoyé sera l adresse IP du client sous le bon format si j'ai bien compris. Mais je peux aussi utiliser la fonction getpeername:
int getpeername(int s, struct sockaddr *name, socklen_t *namelen) qui est cencé renvoyer l adresse IP et le port TCP correspondant a la socket s.
1) quel est la difference entre gatpeername et inet_ntoa puisque les 2 nous donne l adresse IP (à part le fait que le getpeername renvoi aussi le port TCP)
2) Dans toutes les documentations on voit " int getpeername(...) " , comment il peut renvoyer 2 choses, il faut une structure pour ca.C'est le int que je comprends pas.
en definitive, ces 2 questions montrent que j ai pas bien compris l'utilité ET la maniere de me servir de getpeername.
3)Supposons que tout se passe bien jusqu au :
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
fprintf(stderr, "Error in server: can't bind local address\n");
return(0);
}
et que le bind se passe mal pour une raison quelconque, on va "imprimer" error in server et quitter le programme mais le socket qui etait ouvert depuis tout a l heure restera ouvert ? donc il faudrait avant le return "close(socket", qu est ce que vous en pensez? Et ce serait pareil pour un peu plus loin si le accept se passe mal , il faut faire un close??
4)D apres ce que j ai compris "newsockfd" est là pour chaque client. et des qu on a fait "str_echo(newsockfd)" on ferme newsockfd.Ca ok.Mais sockfd est le socket chargé de la connexion, on devrait fermer ce socket à un moment donné? si la reponse est "non" alors ma ligne close(sockfd) ne sert à rien. Si la reponse est oui alors il y a un probleme parce que quand je regarde mon programme, on sort jamais du for(;;) donc on fait jamais close(sockfd)!!!!
En resumé le getpeername et les fermetures de sockets sont pas super clair à mes yeux. Apres ca je pense que j'aurai plus de question.
je vous remercie d avance de m'avoir lu jusqu au bout.
legyptien
Messages postés
382
Date d'inscription
lundi 19 novembre 2007
Statut
Membre
Dernière intervention
23 avril 2022
9
1 janv. 2008 à 22:32
1 janv. 2008 à 22:32
La question 2 n'a plus lieu d'etre car getpeername renvoi 0 si l'adresse a bien été charger dans name avec int getpeername(int s, struct sockaddr *name, socklen_t *namelen). En fait getpeername ne renvoie pas l adresse IP , il charge dans une structure.
Tout bien reflechi le getpeername n est pas utile parce que grace au "accept " on dispose des informations client donc la question 1 est resolu aussi mais une confirmation de votre part ma rassurerai...
merci à vous.
Tout bien reflechi le getpeername n est pas utile parce que grace au "accept " on dispose des informations client donc la question 1 est resolu aussi mais une confirmation de votre part ma rassurerai...
merci à vous.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
3 janv. 2008 à 10:15
3 janv. 2008 à 10:15
inet_ntoa() est une fonction de conversion de l'adresse IP écrite en "langage machine" vers une écriture lisible par un homme. Elle ne fait appel à aucune fonction réseau. getpeername(), va à partir du socket aller récupérer la structure sock_addr.
je ne pense pas que ça soit utile d'utiliser getpeername(), car il me semble que le port est inclu dans la structure sock_addr.
Pour le reste, je ne sais pas trop. Je pense que le socket doit être libérer automatiquement à la fin, ou éventuellement par l'OS.
je ne pense pas que ça soit utile d'utiliser getpeername(), car il me semble que le port est inclu dans la structure sock_addr.
Pour le reste, je ne sais pas trop. Je pense que le socket doit être libérer automatiquement à la fin, ou éventuellement par l'OS.
legyptien
Messages postés
382
Date d'inscription
lundi 19 novembre 2007
Statut
Membre
Dernière intervention
23 avril 2022
9
3 janv. 2008 à 12:54
3 janv. 2008 à 12:54
salut, désolé je lis plein de truc sur client/serveur mais j ai encore des questions voila le bind:
1)
bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) et le bind est definie comme ceci :
int bind(int sockfd, struct sockaddr *my_addr, int addrlen); le second argument est un pointeur sur structure (qui est du type sockaddr) . jusqu a la c bon.
quand on appel cette fonction le second argument doit etre une adresse puisque dans la definition du bind c est un pointeur (meme si il pointe sur une structure) en fait moi j aurais vu un truc comme ca:
bind(sockfd, &serv_addr, sizeof(serv_addr)) puisqu un pointeur on doit toujours lui passer une adresse en parametre.
2)"sizeof" d une structure je vois pas ce que c est , c est ni le nombre d elements qui compose cette structure ni le "cumule" de la place que prend chaque elements de cette structure puisque j ai testé ca
int main (void)
{
struct sockaddr_in a;
printf("la taille de a est %d \n",sizeof(a));
return(0);
}
ca me donne 16 . je sais que toutes ces questions (sur les pointeurs , les structures etc..) sont basiques , c est des lacunes sur le langage C et pas sur la programation client/serveur...
1)
bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) et le bind est definie comme ceci :
int bind(int sockfd, struct sockaddr *my_addr, int addrlen); le second argument est un pointeur sur structure (qui est du type sockaddr) . jusqu a la c bon.
quand on appel cette fonction le second argument doit etre une adresse puisque dans la definition du bind c est un pointeur (meme si il pointe sur une structure) en fait moi j aurais vu un truc comme ca:
bind(sockfd, &serv_addr, sizeof(serv_addr)) puisqu un pointeur on doit toujours lui passer une adresse en parametre.
2)"sizeof" d une structure je vois pas ce que c est , c est ni le nombre d elements qui compose cette structure ni le "cumule" de la place que prend chaque elements de cette structure puisque j ai testé ca
int main (void)
{
struct sockaddr_in a;
printf("la taille de a est %d \n",sizeof(a));
return(0);
}
ca me donne 16 . je sais que toutes ces questions (sur les pointeurs , les structures etc..) sont basiques , c est des lacunes sur le langage C et pas sur la programation client/serveur...
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
3 janv. 2008 à 16:13
3 janv. 2008 à 16:13
Comme tu le dit toi même, ces questions n'ont rien à faire dans ce message, ouvre en un autre on y répondra tout autant. (l'interet est pour la recherche des messages plus tard)
Pour sizeof, regarde là : https://en.cppreference.com/w/cpp/keyword/sizeof
ça renvoie bien la taille en octet. et pourquoi la taille de a ne serai pas 16 ?
Pour le 1), il n'y a pas de question, je ne voi pas ce qui t'embete. Ou alors, tu ne comprend pas le (struct sockaddr *).
&serv_addr est de type "struct sockaddr_in*", ok ? seulement dans bind il faut passer un "sockaddr*", donc on fait un cast sauvage, comme on aurai pu faire :
int f(int* t){...}
float a=6465;
int i=f((int*)&a);
J'espère avoir deviner ta question.
Pour sizeof, regarde là : https://en.cppreference.com/w/cpp/keyword/sizeof
ça renvoie bien la taille en octet. et pourquoi la taille de a ne serai pas 16 ?
Pour le 1), il n'y a pas de question, je ne voi pas ce qui t'embete. Ou alors, tu ne comprend pas le (struct sockaddr *).
&serv_addr est de type "struct sockaddr_in*", ok ? seulement dans bind il faut passer un "sockaddr*", donc on fait un cast sauvage, comme on aurai pu faire :
int f(int* t){...}
float a=6465;
int i=f((int*)&a);
J'espère avoir deviner ta question.
legyptien
Messages postés
382
Date d'inscription
lundi 19 novembre 2007
Statut
Membre
Dernière intervention
23 avril 2022
9
3 janv. 2008 à 16:39
3 janv. 2008 à 16:39
nickel tu as repondu a mes 2 questions et tu as bien deviné ma 1ere question. pour ce qui est du cast sauvage ,c est pas net mais j ai pas encore tapper cast sauvage sur google et je ne me suis pas documenter la dessus. La prochaine fois je ferais un post à part si je sorts un peu du sujet.
merci à toi ;)
merci à toi ;)