Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1030 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [C/Reseau] Petite explication niveau sockets please...

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C/Reseau] Petite explication niveau sockets please...

n°210823
Tetedeienc​h
Head Of God
Posté le 09-09-2002 à 03:07:59  profilanswer
 

Je dois faire une relation client/server en C, pour l'instant ca se limite a :
 
Je lance le serveur qui attend un paquet.
 
Je lance le client qui balance un paquet au serveur pour dire bonjour et lui filer son IP dedans.
 
Le serveur envoie un paquet de confirmation au client.
 
Je vais donc avoir besoin de sockets pour faire ca...
 
J'ai declare deux sockets pour le client ( Un pour envoyer, un pour recevoir ) et deux pour le serveur ( idem).
 
Ma question est :  
 
-On peut utiliser un meme socket pour envoyer/recevoir des paquets ?
 
-Si je lance le serveur et le client sur la meme becane, ca fera 4 sockets sur le meme port... c'est pas un peu beaucoup ?
 
Pour l'instant, le client envoie un paquet au serveur. Ce dernier le recoit bien, et envoie son paquet de confirmation... mais le client le recoit jamais :/
 
D'ou mes questions sur les sockets...
 
Ah vi, si on a un paquet, on peux connaitre l'IP de l'envoyeur, meme si elle n;est pas dans le "contenu" du paquet ?
 
Merci ;)


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
mood
Publicité
Posté le 09-09-2002 à 03:07:59  profilanswer
 

n°210837
slvn
Posté le 09-09-2002 à 08:50:40  profilanswer
 

faut pas ouvrir 4 sockets !
 
seulement un de chaque coté:)
si t en mets plusieurs sur un même port, ca porte un autre nom ;)
 
si ton paquete de "retour" ne fait juste que confirmer, alors c pas la peine, suffit d'utilier des socket TCP, et t'aura le meme resultat.
 
l'IP de l envoyer est dnas le paquet :),
si tu l enleve ou si tu la changes, spa bien;)


Message édité par slvn le 09-09-2002 à 08:51:09
n°210861
mrbebert
Posté le 09-09-2002 à 10:06:40  profilanswer
 

- Une socket (y compris en TCP), ca marche dans les 2 sens. Inutile d'en créer 2 sur le client.
Pour le serveur, c'est un peu différent. Tu crées une socket particulière, qui se met en attente de connexion (ton appli reste bloquée à ce moment là. A toi d'en tenir compte). Dès qu'une connexion arrive (un client qui cherche à se connecter), la fonction dans laquelle tu étais bloqué retourne un résultat, qui est une nouvelle socket, connectée chez le client. Tu communiques donc avec le client sur cette nouvelle socket, et tu peux remettre la première socket en attente, au cas où un nouveau client arrive.
 
- Pour le serveur, tu dois fixer le numéro de port (faut bien que le client sache où s'adresser). Par contre, pour le client, c'est inutile. Tu peux laisser le système trouver un port disponible tout seul.
 
- Quand une socket est connectée, on peut connaître l'IP/port de celui qui est de l'autre côté (je parle de socket connectées, c'est à dire en TCP. En UDP, c'est différent).
 

n°210864
juju-le-ba​rbare
Posté le 09-09-2002 à 10:20:40  profilanswer
 

Salut,
 
Je me débrouille pas mal en client/serveur en C (si moi je dis ça, et bien !).
Si tu veux une aide dévouée :) , mail moi (juju-le-barbare@fr.fm)
 
@++


---------------
Du temps à perdre ? -> http://www.juju-le-barbare.fr.fm
n°211243
Tetedeienc​h
Head Of God
Posté le 09-09-2002 à 18:31:15  profilanswer
 

ah vi, je dois absolument utiliser les sockets UDP...
 
Donc en gros, 2 sockets de chaque cote ca sert a rien ? je vais tester...


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°211247
Tetedeienc​h
Head Of God
Posté le 09-09-2002 à 18:36:54  profilanswer
 

Arf, quand je mets 2 sockets differents, le bind marche bieng.
 
Si j;utilise le meme, le bind passe pas...
 
Donc y en faut bien 2 differents non ?


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°211251
Tetedeienc​h
Head Of God
Posté le 09-09-2002 à 18:55:03  profilanswer
 

d'ailleurs, en clair, il sert a quoi le bind...
 
:heink:
 
Pourquoi il en faut un avant de recevoir et pas avant d'envoyer...
 
bon, j'ai pondu ca :
 
server.c

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <netdb.h>
  11. #define MYPORT 4950    // the port users will be connecting to
  12. #define MAXBUFLEN 100
  13. typedef struct {
  14.   int packet_ID;
  15.   int client_ID;
  16.   struct in_addr client_IP;
  17.   int client_port;
  18. } pack;
  19. int main(int argc, char *argv[])
  20. {
  21.   int sockfd;
  22.    int sockfd2;
  23.   struct sockaddr_in my_addr;    // my address information
  24.   struct sockaddr_in their_addr; // connector's address information
  25.   struct hostent *he;
  26.   struct hostent *me;
  27.   int addr_len;
  28.   pack p,p2;
  29.  
  30.   my_addr.sin_family = AF_INET;         // host byte order
  31.   my_addr.sin_port = htons(MYPORT);     // short, network byte order
  32.   my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
  33.   memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
  34.  
  35.  
  36.   if (argc != 2) {
  37.     fprintf(stderr,"usage: client hostname \n" );
  38.     exit(1);
  39.   }
  40.  
  41.   if ((me=gethostbyname("localhost" )) == NULL) {  // get the host info
  42.     perror("gethostbyname" );
  43.     exit(1);
  44.   }
  45.  
  46.   if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  47.     perror("socket" );
  48.     exit(1);
  49.   }
  50.  
  51.   if ((sockfd2 = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  52.     perror("socket" );
  53.     exit(1);
  54.   }
  55.   // attente de paquet
  56.   if (bind(sockfd2, (struct sockaddr *)&my_addr,
  57.    sizeof(struct sockaddr)) == -1) {
  58.     perror("bind" );
  59.     exit(1);
  60.   }
  61.  
  62.   addr_len = sizeof(pack);
  63.   if ((recvfrom(sockfd2, &p2, MAXBUFLEN-1 , 0,
  64.  (struct sockaddr *)&their_addr, &addr_len)) == -1) {
  65.     printf("ca a merde\n" ); 
  66.     perror("recvfrom" );
  67.     exit(1);
  68.   }
  69.   if (p2.packet_ID == 121)
  70.     {
  71.       their_addr.sin_family = AF_INET;     // host byte order
  72.       their_addr.sin_port = htons(p2.client_port); // short, network byte order
  73.       //      their_addr.sin_addr = *((struct in_addr *)&(p2.client_IP));
  74.       their_addr.sin_addr = *((struct in_addr *)me->h_addr);
  75.       memset(&(their_addr.sin_zero), '\0', 8);  // zero the rest of the struct
  76.       // Confirmation Packet
  77.       p.packet_ID = 131;
  78.       p.client_ID = 0;
  79.       p.client_IP = *((struct in_addr *)me->h_addr);
  80.       p.client_port = MYPORT;
  81.      
  82.       if ((sendto(sockfd2, &p, sizeof(pack), 0,
  83.    (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
  84.         perror("sendto" );
  85.         exit(1);
  86.       }
  87.       printf("paquet envoye\n" );     
  88.      
  89.     }
  90.   close(sockfd);
  91.   close(sockfd2);
  92.  
  93.   return 0;
  94. }


 
Client.c

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <netdb.h>
  11. #define MYPORT 4950    // the port users will be connecting to
  12. #define MAXBUFLEN 100
  13. typedef struct {
  14.   int packet_ID;
  15.   int client_ID;
  16.   struct in_addr client_IP;
  17.   int client_port;
  18. } pack;
  19. int main(int argc, char *argv[])
  20. {
  21.   int sockfd;
  22.   int sockfd2;
  23.   struct sockaddr_in my_addr;    // my address information
  24.   struct sockaddr_in their_addr; // connector's address information
  25.   struct hostent *he;
  26.   struct hostent *me;
  27.   int addr_len;
  28.   pack p,p2;
  29.     my_addr.sin_family = AF_INET;         // host byte order
  30.     my_addr.sin_port = htons(MYPORT);     // short, network byte order
  31.     my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
  32.     memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
  33.   if (argc != 2) {
  34.         fprintf(stderr,"usage: client hostname \n" );
  35.         exit(1);
  36.     }
  37.  
  38.     if ((he=gethostbyname(argv[1])) == NULL) {  // get the host info
  39.         perror("gethostbyname" );
  40.         exit(1);
  41.     }
  42.     if ((me=gethostbyname("localhost" )) == NULL) {  // get the host info
  43.         perror("gethostbyname" );
  44.         exit(1);
  45.     }
  46.     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  47.         perror("socket" );
  48.         exit(1);
  49.     }
  50.     if ((sockfd2 = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  51.         perror("socket" );
  52.         exit(1);
  53.     }
  54.     their_addr.sin_family = AF_INET;     // host byte order
  55.     their_addr.sin_port = htons(MYPORT); // short, network byte order
  56.     their_addr.sin_addr = *((struct in_addr *)he->h_addr);
  57.     memset(&(their_addr.sin_zero), '\0', 8);  // zero the rest of the struct
  58.     // Registration Packet
  59.     p.packet_ID = 121;
  60.     p.client_ID = 0;
  61.     p.client_IP = *((struct in_addr *)me->h_addr);
  62.     p.client_port = MYPORT;
  63.    
  64.     if ((sendto(sockfd, &p, sizeof(pack), 0,
  65.       (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
  66.         perror("sendto" );
  67.         exit(1);
  68.     }
  69.     printf("paquet envoye\n" );
  70.     // attente du paquet de retour...
  71.        if (bind(sockfd2, (struct sockaddr *)&my_addr,
  72.      sizeof(struct sockaddr)) == -1) {
  73.       perror("bind" );
  74.       exit(1);
  75.       }
  76.     addr_len = sizeof(pack);
  77.     if ((recvfrom(sockfd, &p2, MAXBUFLEN-1 , 0,
  78.  (struct sockaddr *)&their_addr, &addr_len)) == -1) {
  79.       printf("ca a merde\n" ); 
  80.       perror("recvfrom" );
  81.         exit(1);
  82.     }
  83.    
  84.     close(sockfd);
  85.     close(sockfd2);
  86.    
  87.     return 0;
  88. }


 
Vous me dites c'est du bidouillage je vous reponds ouiiiiiiiiiiii ;)
 
Mais bon, avec ca, le server attends son paquet, je lance le client qui envoie son paquet, le server le recoit et trouve le bon contenu, envoie le sien... que le client recit jamais :/
 
Vous pouvez m'expliquer ?
 


Message édité par Tetedeiench le 09-09-2002 à 19:11:23

---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°211287
Tetedeienc​h
Head Of God
Posté le 09-09-2002 à 20:06:30  profilanswer
 

beng ?
 
Chuis vraiment bloqued la :/


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°211345
slvn
Posté le 09-09-2002 à 21:37:05  profilanswer
 

c quoi le pb en fiat ?!
 
t as bien initialise les structures  sockaddr ?!
 -> ou ca pose pb ?
   a la creation du socket ? au bind ? au send ? au recv ?

n°211404
oliv5
Pourquoi ? Parce que !
Posté le 09-09-2002 à 23:49:00  profilanswer
 

Hum, perso, en UDP j'ai toujours ouvert 2 sockets sur le client et 2 sur le serveur.Ca marchait bien et je crois pas que tu puisse faire autrement.
 
Cependant, en TCP je te confirme qu'une seule socket (c masculin ou féminin je sais jamais) sur le client suffit et 2 sur le serveur (1 socket de rendez-vous où le client se connecte au début, et 1 socket par client). En TCP une socket marche dans les 2 sens.
 
En UDP, je suis pas sûr !

mood
Publicité
Posté le 09-09-2002 à 23:49:00  profilanswer
 

n°211407
slvn
Posté le 09-09-2002 à 23:56:30  profilanswer
 

arf, j'ai un doute, mais je crois que j'ai jamais fait 2 socket en udp....
 
server : create -> bind -> recvfrom/sendto                  
client : create -> recvfrom/sendto    
 
pour ton socket udp, tu mets :  
AF_INET, SOCK_STREAM, IPPROTO_TCP comme para ?!  
       

n°211411
juju-le-ba​rbare
Posté le 10-09-2002 à 00:28:37  profilanswer
 

nop !
 
Ya toujours qu'un seul socket de chaque coté !
Ces 2 sockets forment un seul tube de communication (connecté ou non selon que c'est TCP/UDP)
 
Si tu veux créer plusieurs sockets, c'est éventuellement du côté serveur TCP, qui lorsqu'il reçoit une connection d'un client créé une socket puis fork le processus, et pendant ce temps le père se remet en écoute (on peut définir le nombre maxi de clients dans l'appel à listen())
N'oublie pas select() si tu veux autoriser plusieurs clients.
 
@++


---------------
Du temps à perdre ? -> http://www.juju-le-barbare.fr.fm
n°211438
Tetedeienc​h
Head Of God
Posté le 10-09-2002 à 02:56:09  profilanswer
 

ouiiiiiiiii merci ca maaaaaaaaaarche :love:
 
Je reviendrai surement poser des questions, mais l;echange de paquets fonctionne enfin :love:


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°211462
mrbebert
Posté le 10-09-2002 à 10:02:02  profilanswer
 

Tetedeiench a écrit a écrit :

ah vi, je dois absolument utiliser les sockets UDP...
 
Donc en gros, 2 sockets de chaque cote ca sert a rien ? je vais tester...



En UDP, c'est différent. Tu n'as pas la notion de connexion.
Dans ce cas, une seule socket suffira côté serveur. Elle recevra les paquets de tous les clients, et tu peux regarder pour chacun d'eux d'où il vient (pratique si tu veux envoyer une réponse).
 
UDP respecte les limites des paquets. C'est à dire que si un client envoie un paquet de 149 octets, le serveur recevra d'un seul bloc les 149 octets. Où ne recevra rien du tout.
Il n'y aucun engagement sur le fait que le paquet ait été reçu. C'est à toi de mettre en place un dispositif d'accusé réception si tu as besoin d'être sur que la paquet est bien arrivé à destination (contrairement à TCP).
 
Pour le bind, ce n'est pas obligatoire. Tu t'en sert si tu veux que ta socket soit sur un port déterminé. Sinon, c'est l'OS qui te la met où il veut.

n°211658
juju-le-ba​rbare
Posté le 10-09-2002 à 15:39:08  profilanswer
 

Tetedeiench a écrit a écrit :

ouiiiiiiiii merci ca maaaaaaaaaarche :love:
 
Je reviendrai surement poser des questions, mais l;echange de paquets fonctionne enfin :love:




 
ben dis nous plutôt ce que tu as fait pour que ça marche ;)


---------------
Du temps à perdre ? -> http://www.juju-le-barbare.fr.fm
n°211750
oliv5
Pourquoi ? Parce que !
Posté le 10-09-2002 à 17:38:39  profilanswer
 

mrbebert a écrit a écrit :

En UDP, c'est différent. Tu n'as pas la notion de connexion.
Dans ce cas, une seule socket suffira côté serveur. Elle recevra les paquets de tous les clients, et tu peux regarder pour chacun d'eux d'où il vient (pratique si tu veux envoyer une réponse).
 
UDP respecte les limites des paquets. C'est à dire que si un client envoie un paquet de 149 octets, le serveur recevra d'un seul bloc les 149 octets. Où ne recevra rien du tout.
Il n'y aucun engagement sur le fait que le paquet ait été reçu. C'est à toi de mettre en place un dispositif d'accusé réception si tu as besoin d'être sur que la paquet est bien arrivé à destination (contrairement à TCP).
 
Pour le bind, ce n'est pas obligatoire. Tu t'en sert si tu veux que ta socket soit sur un port déterminé. Sinon, c'est l'OS qui te la met où il veut.




 
tout à fait d'accord !  :jap: Je m'en rapelle jamais, mais c'est ca !

n°211928
Tetedeienc​h
Head Of God
Posté le 11-09-2002 à 04:50:04  profilanswer
 

juju-le-barbare a écrit a écrit :

 
 
ben dis nous plutôt ce que tu as fait pour que ça marche ;)




 
j'ai tout repris a zero.
 
En bidouillant un seul socket de chaque cote, et en ne bindant QUE du cote server.
 
Chai pas pkoi, mais ca amrche d'enfer ;)
 
Me reste a threader le bordel et zouuuu, project closed :sol:
 
Va falloir que je demande au prof aussi comment il envoie un entier dans un paquet... de telle sorte qu;il soit lisible par n'importe quelle becane, que ce soit un Sparc qu'un RISC ou un CISC...
 
Car la, en changeant d'archi, ca merde legerement :/


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°211991
mrbebert
Posté le 11-09-2002 à 09:39:23  profilanswer
 

regarde les fonction ntohl et htonl :
- htonl convertit un long au format 'network'
- ntohl convertit du format network au format local utilisé par la machine
http://search.microsoft.com/gomsur [...] tohl_2.asp
 
De même, tu as htons pour les entiers sur 2 octets.
 
Edit : ce lien là est mieux :
http://search.microsoft.com/gomsur [...] dering.asp


Message édité par mrbebert le 11-09-2002 à 09:40:46

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [C/Reseau] Petite explication niveau sockets please...

 

Sujets relatifs
Petite macro Exceltransformation prog java en applet java pr mettre sur internet please
[TCL/Tk] Encore une petite questionSockets, PHP, newsletter... comment ça marche ?
[Sockets en C/C++ sous UNIX] Bon livre ???[zindozs] en bas niveau, afficher des pixels dans une fenetre
[win2k]savoir la bande passante pris par chaque utilisateur du reseau?[vb6]obtenir l'ip de tous les PC du reseau local !
comment ajouter une image a un fichier php PLEASEequivalent du paseInt en vbscript attention petite subtilité!!
Plus de sujets relatifs à : [C/Reseau] Petite explication niveau sockets please...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR