Telnet en C [C - Newby] - C++ - Programmation
Marsh Posté le 26-10-2003 à 17:25:08
il y a une rubrique c, et une c++, ici on est dans la c++
sinon, tu veux apparement binder ton port local 80, as-tu vérifié qu'il n'etait pas déjà utilisé ?
Marsh Posté le 26-10-2003 à 17:27:32
oups dsl pour la rubrique.
mon port 80 est le port http de ma machine donc je pense que c'est le bon port à utiliser. De plus l'erreur ne viens pas du bind mais du connect.
Marsh Posté le 26-10-2003 à 19:54:39
tu compiles sous quel OS ?
Marsh Posté le 26-10-2003 à 21:09:59
pour détereminer les pbs et débuguer plus facilement ton application, sécurise la déjà : par exemple, vérifie la valeur de retour de tes fonctions, style :
if(sock = socket(...) == false)
// affiche message
ça t'aidera à savoir ce qui marche ou pas. Prendre cette habitude est primordiale en prod, et spécialement en socket où ça ne marche jamais comme on veut
Marsh Posté le 26-10-2003 à 21:44:17
Code :
|
Code :
|
C'est grâce à ces tests que j'ai pu voir que le connect ne marche pas : perror() du connect me retourne invalid argument
Marsh Posté le 26-10-2003 à 23:16:59
Regarde ces lignes :
memcpy(&cli.sin_addr,he->h_addr,sizeof(cli.sin_addr));
memcpy(&srv.sin_addr,he->h_addr,sizeof(srv.sin_addr));
Dans la définition de la structure sockaddr_in, le membre sin_addr est une structure de type in_addr. T'as pas l'impression de faire un peu n'importe quoi là ? Pas étonnant que je me prenne une segmentation fault si je lance ton programme en n'étant pas connecté au net...
Pour info, le membre qui contient les adresses est sockaddr_in.sin_addr.s_addr.
Ce qui nous donne :
Code :
|
Regarde au moins la définition des structures la prochaine fois...
Marsh Posté le 27-10-2003 à 14:43:07
ok mais pourquoi ça fonctionne parfaitement lorsque l'on fait tourner le serveur et le client sur la même machine? j'ai compilé avec ce que tu m'as gentiment conseillé mais j'ai toujours la même erreur : Connect:Invalid Argument (et un segmentation fault quand je ne suis pas connecté à Internet )
Marsh Posté le 27-10-2003 à 22:40:23
J'ai repris ton source un peu plus en détail, je l'ai modifié et il marche. Ne compte pas sur moi pour te donner le source, ça serait trop facile. Je te donne juste quelques pistes :
- il te faut 2 sockets : 1 client et 1 serveur. Pourquoi 2 sockets ? Tout simplement parce que le 1er paramètre de la fonction socket() change selon qu'il s'agit d'un client ou d'un serveur et leur fonction n'est pas la même
- les memset() pour vider la structure sockaddr_in, c'est bien, manges en
- si tu veux éviter la segmentation fault en n'étant pas connecté au net, je te conseille de tester la valeur de retour de gethostbyname("www.yahoo.fr" )
- la valeur que tu donnes au membre sin_family de ta structure sockaddr_in n'est pas bon. regarde plutot du coté de he->h_addrtype
- si tu tiens vraiment à utiliser le membre sin_addr de ta structure sockaddr_in, tape plutot un truc du genre :
Code :
|
voici ce que j'obtiens :
Citation : |
à toi de jouer maintenant...
Marsh Posté le 28-10-2003 à 09:17:56
Il n'a besoin que d'un socket effectivement, mais je suppose que s'il a mis le socket "localhost", c'est qu'il compte l'utiliser par la suite
Mais c'est clair que tel qu'il est codé dans son source, il ne sert à rien du tout (il est bindé, mais sans listen() ou connect() derrière, etc..)
Marsh Posté le 28-10-2003 à 09:38:56
je vois pas pourquoi il faudrait 2 sockets. Le listen est géré par le serveur. Ce code fonctionne parfaitement lorsque je fais tourner un serveur sur une machine du même réseau que le client.
Marsh Posté le 28-10-2003 à 09:52:05
Alors à quoi te servent ces lignes ?
Code :
|
Pourquoi bindes tu un socket avec localhost si ensuite tu utilises ce socket pour te connecter sur yahoo ?
J'ai supprimé ces lignes et ça fonctionne très bien, en faisant les modifs que je t'ai donné plus haut, j'arrive à me connecter sur le serveur de yahoo sans problème
Marsh Posté le 28-10-2003 à 10:59:24
il faut bien construire la structure sockaddr_in cli pour savoir sur quel port on travaille sur la machine local nan?
le bind est là pour associer un port à la socket.
Marsh Posté le 28-10-2003 à 11:07:31
pourquoi veux tu indiquer le port sur lequel travaille la machine locale ?
moi j'ai enlevé de ton source toute la partie qui concerne la structure cli (les lignes de mon post précédent), et ça marche bien
edit: le bind() serait utile si tu faisais un listen() derrière, pour un connect(), à mon avis c'est inutile
Marsh Posté le 28-10-2003 à 11:16:16
parce qu'une socket à toujours un numéro de port associé!
de toute façon l'erreur ne vient pas de là.
edit: en tcp on a:
client : bind puis connect (il est vrai que le bind n'est pas obligatoire que le connect s'en charge).
serveur : listen puis accept
le client ne fait jamais de listen et donc jamais d'accept.
Marsh Posté le 28-10-2003 à 11:19:50
dudul51 a écrit : parce qu'une socket à toujours un numéro de port associé! |
J'en suis pas si sûr... Déjà ton utilisation du port 80 pour le client est louche, j'essairai avec un port > 1024, et puis la plus part du temps on se fout de savoir quel port on utilise pour sortir
Marsh Posté le 28-10-2003 à 11:20:59
Harkonnen a écrit : pourquoi veux tu indiquer le port sur lequel travaille la machine locale ? |
Si j'ai bien tout compris à la chose, c utile si tu veux utiliser un port spécifique pour sortir... mais la son port 80 c'est une mauvaise idée.
Marsh Posté le 28-10-2003 à 11:49:53
dudul51 a écrit : parce qu'une socket à toujours un numéro de port associé! |
oui merci je le sais
mais si tu ne fais aucun listen(), je vois pas l'utilité de binder ton socket à localhost
dudul51 a écrit : |
Non elle ne vient pas de là. J'ai corrigé ton source selon les indications que je t'ai donné plus haut, et ça fonctionne très bien, avec ou sans le bind() de toute façon. Essaie de trouver l'erreur par toi même, je ne t'aiderais pas si je te donne le source tout fait.
Marsh Posté le 28-10-2003 à 16:29:08
LetoII a écrit : |
c'est le port http le port 80 et je veux me connecter à un serveur pour exécuter une requête http.
Marsh Posté le 28-10-2003 à 16:34:04
dudul51 a écrit : |
Oui mais tu ton client peut utiliser n'importe quel port pour sortir.
Marsh Posté le 28-10-2003 à 16:41:44
c'est vrai, je viens d'essayer avec un port différent et ça marche. Je pensais que la socket du client devait être associée elle aussi au port 80. Merci.
Marsh Posté le 28-10-2003 à 16:41:58
De toute façon, un bind() est inutile si tu cherches à te connecter à un site web, à mon avis. Un connect() suffit, et ensuite tu utilises les fonctions send() et recv() pour dialoguer avec le site.
Marsh Posté le 28-10-2003 à 16:46:52
pour info, voici ce que j'ai fait :
Code :
|
Marsh Posté le 28-10-2003 à 21:44:50
Il est vrai que sans le bind() ça marche aussi. Merci pour ton aide.
Marsh Posté le 29-10-2003 à 04:25:42
Pour info, si tu ne fais pas de bind(), alors le connect() prend un numéro de port aléatoire au dessus de 1024. Et c'est la bonne façon de faire, sauf besoin particulier (du genre un firewall qui ne laisse sortir que quelques ports bien particuliers).
Au final tu as côté serveur une socket bindée sur le port 80, et côté client une socket bindée sur un port arbitraire au dessus de 1024.
Marsh Posté le 26-10-2003 à 17:22:26
Voilà mon problème : j'essaie d'écrire un client qui se connecte à un site web à partir d'une socket en tcp. Ensuite l'utilisateur peut taper une requête HTTP vers se serveur. La réponse du serveur est alors affichée à l'écran. Voici mon code :
avec ce code j'essaie de me connecter sur yahoo pour envoyer ma requête mais j'ai une erreur au niveau du connect : Invalid argument et je ne voit pas d'où ça vient : de la construction de srv, des ports???
Quelqu'un peut m'aider?