probleme avec un gethostbyaddr() - C - Programmation
Marsh Posté le 12-11-2004 à 11:43:35
ben c'est pas compliqué. Il faut passer &you.sin_addr et &me.sin_addr à gethostbyaddr (avec le sizeof qui va bien). Et tant qu'à y être, testez les retours de fonction et les pointeurs; ce ne sera pas du luxe et cela vous évitera et d'avoir un segfault et d'avoir à utiliser gdb pour trouver d'où il vient.
Marsh Posté le 13-11-2004 à 10:18:07
Merci DocMaboul pour ta reponse,
et donc voila c'est fait j'ai mis &me.sin_addr et &you.sin_addr dans les gethostbyaddr() :
void log_connexion(int sd)
{
int size = sizeof(struct sockaddr);
struct sockaddr_in me,you;
struct hostent *h_you,*h_me;
my_getsockname(sd,(struct sockaddr *)&me,(socklen_t *)&size);
my_getpeername(sd,(struct sockaddr *)&you,(socklen_t *)&size);
h_you = my_gethostbyaddr((char *)&you.sin_addr,sizeof(you.sin_addr),AF_INET);
h_me = my_gethostbyaddr((char *)&me.sin_addr,sizeof(me.sin_addr),AF_INET);
fprintf(stderr,"Serveur <%s> (%s:%d) connecte a la machine distante <%s> (%s:%d)\r\n",
h_me->h_name,inet_ntoa(me.sin_addr),ntohs(me.sin_port),
h_you->h_name,inet_ntoa(you.sin_addr),ntohs(you.sin_port));
fflush(stderr);
}
(Les fonctions commençant par my_ font l'appel de la fonction correspondante et teste la valeur de retour...)
Et donc ça marche si je teste en local : si sur mon PC j'ouvre un navigateur et que je met "http://localhost:8080/..." tout est ok, mais si je vais sur un autre ordi de mon reseau local, que je tape "http://192.168.0.130:8080/..." (192.168.0.130 est l'adresse de mon PC) là sa plante
dans le premier gethostbyaddr()...
Je comprend pas pourquoi...
Marsh Posté le 13-11-2004 à 11:01:32
Bon, il y a manifestement d'autres erreurs dans votre code. Quelques remarques:
Déjà, vous faites une utilisation douteuse de inet_ntoa. Le mieux serait de faire les appels avant le printf, de stocker ça à part (en dupliquant la chaine, hein, pas juste une copie de pointeur) et d'utiliser la chaine dupliquée ensuite.
Aussi, je ne comprends pas pourquoi vous n'utilisez pas des socklen_t mais des int que vous castez ensuite. Il faut aussi réinitaliser size entre l'appel à getsockname et getpeername. Le problème vient probablement de là.
Le fflush(stderr) est inutile (le gros avantage de stderr pour les trace de debug est qu'on n'a justement pas de buffeur de sortie).
Marsh Posté le 12-11-2004 à 10:59:42
Bonjour tout le monde,
voilà je débute en programation réseau et j'ai un petit pb.
Je dois faire un mini-serveur HTTP.
Voici le debut de mon code :
......................
......................
log = open("log.txt",O_WRONLY);
redirect(STDERR_FILENO,log);
sock = socket(AF_INET,SOCK_STREAM,0);
adresse_locale.sin_family = AF_INET;
adresse_locale.sin_addr.s_addr = INADDR_ANY;
adresse_locale.sin_port = PORT;
bind(sock,(struct sockaddr *)(&adresse_locale),
sizeof(adresse_locale));
my_listen(sock,NOMBRE_CONNEXIONS_EN_ATTENTE);
longueur_adresse_appelant = sizeof(adresse_appelant);
while(1)
{
socket_connexion = accept(sock,
(struct sockaddr *)(&adresse_appelant),
(socklen_t *)&longueur_adresse_appelant);
log_connexion(socket_connexion);
/* CODE DU FILS */
if ( fork() == 0 )
{
...............
...............
Voila mon probleme : quand j'appelle la fonction log_connexion :
void log_connexion(int sd)
{
int size = sizeof(struct sockaddr);
struct sockaddr_in me, you;
struct hostent *h_you, *h_me;
struct in_addr addr;
getsockname(sd,(struct sockaddr *)&me,(socklen_t *)&size);
getpeername(sd,(struct sockaddr *)&you,(socklen_t *)&size);
addr.s_addr = inet_addr(inet_ntoa(you.sin_addr));
h_you = gethostbyaddr((char *)&addr.s_addr,
sizeof(addr.s_addr),
AF_INET);
addr.s_addr = inet_addr(inet_ntoa(me.sin_addr));
h_me = gethostbyaddr((char *)&addr.s_addr,
sizeof(addr.s_addr),
AF_INET);
fprintf(stderr,
"Serveur <%s> (%s:%d) connecte a la
machine distante <%s> (%s:%d)\r\n",
h_me->h_name,
inet_ntoa(me.sin_addr),
ntohs(me.sin_port),
h_you->h_name,
inet_ntoa(you.sin_addr),
ntohs(you.sin_port));
fflush(stderr);
}
J'ai une belle "segmentation fault" parce que les (struct hostent *) h_me et h_you sont NULL (testé avec GDB).
Je ne compend pas pourquoi puisque j'ai testé les valeurs de retour de getsockname(), getpeername() et des 2 inet_ntoa() et qu'elles sont ok.
En plus ce que je comprend encore moins, c'est qu'en fait ça marche quand j'appelle mon serveur en local : si je tape "http://localhost:8080/..." ou "http://127.0.0.1/...." ça marche bien mais dès que je l'appelle avec mon adresse ip sa plante...
Autre chose : tout marche nickel si je n'appelle pas la fonction donc sa vient bien d'elle...
Donc si un oeil expert passait par là, merci de me donner un petit coup de main!!! Je suis dessus depuis deux jours j'en ai marre!!!
Merci. pippou