Pages : 1
#1 Le 10/11/2016, à 14:11
- DonutMan75
[RESOLU] [C] Socket, cas d'école
Bonjour,
j'aimerais créer deux programmes client/serveur en C qui communiquerait en local via une socket.
Voici le début de mon code côté client :
struct sockaddr_in myaddress;
bzero(&myaddress, sizeof(myaddress));
myaddress.sin_family = AF_INET;
myaddress.sin_port = htons(21054); // Port quelconque
myaddress.sin_addr.s_addr = INADDR_LOOPBACK; // Localhost
// STEP 1 - CREATION DE LA SOCKET
printf("[CLIENT] Creation of sending socket...\n");
if ((mysocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))<0)
perror("Socket");
// STEP 2 - BIND AVEC LE COUPLE (IP, PORT)
printf("[CLIENT] Binding of the sending socket...\n");
if (bind(mysocket, (struct sockaddr *) &myaddress, sizeof(myaddress))<0)
perror("Bind");
Ca compile bien mais quand j'exécute, j'obtiens :
>> ./client
[CLIENT] Creation of sending socket...
[CLIENT] Binding of the sending socket...
Bind: Cannot assign requested address
Sur le net, je lis que l'explication est que je n'utilise pas une "interface locale" mais je ne comprends pas ce que ça veut dire...
Avez-vous des idées ?
Merci d'avance
Dernière modification par DonutMan75 (Le 27/11/2016, à 08:34)
Hors ligne
#2 Le 12/11/2016, à 13:19
- Bigcake
Re : [RESOLU] [C] Socket, cas d'école
Bonjour,
Coté client tu ne doit pas faire de bind(), c'est uniquement coté serveur, je pense que tu a ce problème car ton serveur est déjà 'bind' au port, 2 applications ne peuvent avoir un bind actif sur le même port dans la même période de temps.
globalement le serveur doit faire dans l'ordre :
- socket()
- bind()
- listen()
ensuite, le client doit faire :
- getaddrinfo() (si besoin)
- socket()
- connect()
"Les gens" ne sont pas cons, ils ont été habitués à la facilité et à la désinformation. Le meilleur moyen de ne pas les aider, c'est de se moquer. Le meilleur moyen de les aider, c'est de les informer, encore et encore. La réflexion viendra. N'oubliez pas que vous aussi, vous êtes le con d'un autre.
Smartphone+GNU/Linux=Librem5
Hors ligne
#3 Le 14/11/2016, à 10:00
- DonutMan75
Re : [RESOLU] [C] Socket, cas d'école
Bonjour Bigcake,
merci pour ta réponse, je vais tester ça
D.
Hors ligne
#4 Le 17/11/2016, à 17:41
- DonutMan75
Re : [RESOLU] [C] Socket, cas d'école
Bonsoir à tous,
en cherchant un peu j'ai réussi à me dépatouiller.
Tout d'abord le bind() me paraît nécessaire à la fois côté client et serveur.
Côté serveur, on indique à bind() le couple (INADDR_ANY, PORTS) pour spécifier qu'on écoute à partir de n'importe quelle interface sur le port PORTS. N'importe quelle interface signifie ici qu'on pourra joindre notre serveur aussi bien depuis la même machine (donc via l'interface LOOPBACK, classiquement en 127.0.0.1) que depuis une autre machine (par exemple 192.168.0.2 qui contacte 192.168.0.1 sur lequel tourne notre serveur)
Côté client, on indique à bind() le couple (INADDR_ANY, PORTC) pour spécifier que les messages seront envoyés via le port client PORTC (qui est généralement différent du port serveur).
Dans mon code, tout s'est résolu (par magie ??) lorsque j'ai remplacé "INADDR_LOOPBACK" par "INADDR_ANY" sans que je sache trop bien pourquoi.... Pour le moment je n'ai pas encore de réponse là dessus, je continue à creuser
Bonne soirée à tous
D.
Hors ligne
#5 Le 17/11/2016, à 19:24
- eiger
Re : [RESOLU] [C] Socket, cas d'école
Salut,
Le bind() côté client n'est en général pas nécessaire. Cela peut être le cas si tu veux forcer l'utilisation d'un port source particulier (même si en général, on laisse la pile de protocoles choisir le port source). Le bind() côté client peut également être utile si tu disposes de plusieurs interfaces réseau et que tu souhaites forcer celle que tu va utiliser pour émettre ta requête.
En revanche concernant ton histoire de INADDR_LOOPBACK / INADDR_ANY, il te manque a priori simplement un appel à htonl:
myaddress.sin_addr.s_addr = INADDR_LOOPBACK; // Localhost
devient
myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // Localhost
INADDR_ANY étant "0.0.0.0", l'oubli de htonl n'a pas d'influence.
En revanche avec INADDR_LOOPBACK, en oubliant le htonl, tu essaies de faire un bind sur l'adresse 1.0.0.127, ce qui ne marche évidemment pas.
Hors ligne
#6 Le 27/11/2016, à 08:34
- DonutMan75
Re : [RESOLU] [C] Socket, cas d'école
Bonjour eiger,
merci beaucoup pour cette réponse (et désolé pour ma réponse tardive) !
Si je comprends bien les conversions vers la représentation "reseau" concerne donc aussi bien les IP et que les ports donc ?
Je peux passer le fil à resolu grâce à vous tous.
Bon dimanche !
D.
Hors ligne