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

  FORUM HardWare.fr
  Programmation
  C

  Structure sockaddr_in

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Structure sockaddr_in

n°1332167
dounia2
Posté le 25-03-2006 à 16:36:28  profilanswer
 

Salut,
 
J'essaie de programmer un serveur UDP et un client UDP aui echangent des messages. Dans mon serveur je veux reccuperer l'adresse IP du client. Pour cela j imprime sut stdout "sin_addr.s_addr" mais je me retrouve avec une adresse nulle.
 
printf("Adresse IP client: %s \n", son_s->sin_addr.s_addr);
 
Quelqu'un peut m'aider?
 
Merci.


Message édité par dounia2 le 25-03-2006 à 17:01:11
mood
Publicité
Posté le 25-03-2006 à 16:36:28  profilanswer
 

n°1332178
nargy
Posté le 25-03-2006 à 17:10:19  profilanswer
 

> son_s->sin_addr.s_addr
- contient une adresse ip sous forme binaire
 
utilise une fonction de conversion:
 
char *inet_ntoa(struct in_addr in);
 

n°1332182
dounia2
Posté le 25-03-2006 à 17:28:10  profilanswer
 

J'ai esseye avec  
 
printf("Adresse %s\n", inet_ntoa(son_s->sin_addr));
 
et il imprime  
 
Adresse 0.0.0.0
 
C'est normal?


Message édité par dounia2 le 25-03-2006 à 17:28:36
n°1332184
ArthurDent
Posté le 25-03-2006 à 17:33:16  profilanswer
 

tu essaie d'afficher l'adresse de la machine sur laquelle le process s'execute ou celle de la machine avec laquelle tu communique?

n°1332186
dounia2
Posté le 25-03-2006 à 17:36:40  profilanswer
 

J'esseye d'afficher l'adresse de la machine sur laquelle le process s'execute (si c une machine distante ca revient a dire la machine avec laquelle je communique, non?..enfin je ne vois pas vraiment la différence entre les deux)..

n°1332187
nargy
Posté le 25-03-2006 à 17:39:03  profilanswer
 

il faudrait que tu montre la partie de code qui accèpte la connexion client et récupère son adresse...
D où vient le ``son_s->sin_addr.s_addr``?

n°1332193
dounia2
Posté le 25-03-2006 à 17:43:19  profilanswer
 

nargy a écrit :

il faudrait que tu montre la partie de code qui accèpte la connexion client et récupère son adresse...
D où vient le ``son_s->sin_addr.s_addr``?


 
Voila le code, pourtant j'ai bien rempli les structures sockaddr_in..
En tout cas merci pour ton aide, je commence à etre fatiguée :)
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "my_socks.h"
  5. /* Note : l'adrese IP du serveur est localost si le client et le serveur sont sur la */
  6. /*     même machine.                 */
  7. int main(int argc, char *argv[])
  8. {
  9. struct sockaddr_in* mon_s;
  10. struct sockaddr_in* son_s;
  11. int     sd, n, num_port_udp;
  12. int     *fromlen;
  13. message*   rcv_mess;
  14. message* send_mess;
  15. int i;
  16. if (argc != 2) {
  17.  printf("Usage : %s <numero_port_udp>\n", argv[0]);
  18.  exit(1);
  19. }
  20. num_port_udp = atoi(argv[1]);
  21. /* Allocation mémoire                 */
  22. mon_s   = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
  23. son_s   = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
  24. rcv_mess   = (message *)malloc(sizeof(message));
  25. send_mess = (message*)malloc(sizeof(message));
  26. fromlen  = (int *)malloc(sizeof(int));
  27. /* On ouvre un socket en mode UDP, datagramme, sur le domaine PF_INET     */
  28. if((sd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
  29. {
  30.  perror("udpser.c: err socket" );
  31.  affiche_errno();
  32. }
  33. /* On remplit la structure d addresse du client par des zeros pour l initialisation */
  34. /* Note du man: "BSD 4.3. bezo est déconseillée, utilisez plutôt memset."   */
  35. memset((char*)mon_s, 0, sizeof(*mon_s));
  36. /* On initialise les champs de la structure.          */
  37. /* Initialisation de l adresse IP de la machine avec n importe quelle carte   */
  38. mon_s->sin_addr.s_addr = INADDR_ANY;
  39. mon_s->sin_family = htonl(AF_INET);
  40. /*initialisation du port du serveur avec des octets en format reseau    */
  41. mon_s->sin_port = htons(num_port_udp);
  42. if((n = bind(sd, (struct sockaddr*)mon_s, sizeof(*mon_s))) == -1)
  43. {
  44.  perror("udpser.c: err bind" );
  45.  affiche_errno();
  46. }
  47. /* Longueur de l adresse recuperee par le serveur (envoyée par le client)   */
  48. *fromlen = sizeof(son_s);
  49. strcpy(send_mess->mtext, "Seurver reponds et envoie un message" );
  50. printf("---------------[Serveur]-----------------" );
  51. printf("\nBind to         : %d %d\n", sd, num_port_udp);
  52. if((n = recvfrom(sd, rcv_mess, sizeof(message), 0, (struct sockaddr*)son_s, (socklen_t *)fromlen)) == -1)
  53. {
  54.  perror("udpser.c: err recvfrom" );
  55.  affiche_errno();
  56. }
  57. printf("Message recu      : \"%s\"\n", rcv_mess->mtext);
  58. printf("Reçu from         : %x %d\n", ntohl(son_s->sin_addr.s_addr), ntohs(son_s->sin_port));
  59. printf("Adresse IP client: \n" );
  60. printf("Adresse %s\n", inet_ntoa(son_s->sin_addr));
  61. /*for(i=0; i<4; i++)
  62. {//inet_ntoa
  63.  printf("%s", son_s->sin_addr.s_addr[i]);
  64.  if(i<3)
  65.   printf("." );
  66.  if(i=3)
  67.   printf("\n" );
  68. }*/
  69. printf("Serveur envoie message...\n" );
  70. if((n = sendto(sd, send_mess, sizeof(message), 0, (struct sockaddr*)son_s, sizeof(*son_s))) == -1)
  71. {
  72.  perror("udpser.c: err sendto" );
  73.  affiche_errno();
  74. }
  75. printf("FIN\n\n" );
  76. /* Libération de la mémoire               */
  77. free(mon_s);
  78. free(son_s);
  79. free(send_mess);
  80. free(rcv_mess);
  81. free(fromlen);
  82. return 0;
  83. }


 

n°1332211
nargy
Posté le 25-03-2006 à 18:08:13  profilanswer
 

1°) INADDR_ANY=0.0.0.0
est utiliser pour indiquer que l on accepte toute adresse ip valide (un ordinateur peut en avoir plusieurs comme par ex. les passerelles internet)

n°1332213
nargy
Posté le 25-03-2006 à 18:12:57  profilanswer
 

2°) il manque un connect quelquepart
 
le bind sert suelement à affecter une adresse ip à la socket, mais pour effecture la connection:
connect() -> côté client
listen() -> côté serveur

n°1332214
nargy
Posté le 25-03-2006 à 18:17:51  profilanswer
 

entre la ligne 55 et 68 ci sessus, il manque:
 
int socket_client=listen(sd,SOMAXCONN);
 

mood
Publicité
Posté le 25-03-2006 à 18:17:51  profilanswer
 

n°1332216
dounia2
Posté le 25-03-2006 à 18:19:11  profilanswer
 

Ben c'est une connection UDP donc je n en ai pas besoin, connect et listen c est pour TCP..

n°1332217
dounia2
Posté le 25-03-2006 à 18:19:40  profilanswer
 

a moins que je n'ai rien compris a UDP..:S

n°1332219
nargy
Posté le 25-03-2006 à 18:20:31  profilanswer
 

3°) ensuite on lit la socket client à l aide de recvfrom
 
----
errata, pour udp tu n a pas besoin de connect côté client, c est juste sendto(...)

n°1332220
nargy
Posté le 25-03-2006 à 18:21:07  profilanswer
 

si si tu as besoin quand même de listen pour udp


Message édité par nargy le 25-03-2006 à 18:21:29
n°1332222
dounia2
Posté le 25-03-2006 à 18:24:18  profilanswer
 

C est bon ArthurDent a trouvé: c'est *fromlen = sizeof(*son_s);
au lieu de *fromlen = sizeof(son_s);  
 
Il fallait avoir l'oeil! En tout cas merci pour ton aide nargy:)
 
Une dernere question:
a l execution  des fois j'obtient:
 
> ./udpser 4679
udpser.c: err bind: Address already in use
 
 errno =29  
Exit 1
 
Tu sais comment liberer le port?

n°1332224
ArthurDent
Posté le 25-03-2006 à 18:26:34  profilanswer
 

killall udpser : ça tuera les eventuels serveurs qui sont encore en execution, meme si c'est bizarre que cela arrive

n°1332225
nargy
Posté le 25-03-2006 à 18:26:58  profilanswer
 

non t a raison pour udp tu faire directement recvfrom

n°1332227
nargy
Posté le 25-03-2006 à 18:29:21  profilanswer
 

c est SO_REUSEADDR à mettre en flag de bind.
 
man 7 socket:

Citation :


SO_REUSEADDR
              Indicates that the rules used in validating  addresses  supplied
              in  a  bind(2)  call  should allow reuse of local addresses. For
              PF_INET sockets this means that a socket may bind,  except  when
              there  is  an active listening socket bound to the address. When
              the listening socket is bound to INADDR_ANY with a specific port
              then  it  is  not  possible  to  bind to this port for any local
              address.


n°1332229
nargy
Posté le 25-03-2006 à 18:31:07  profilanswer
 

sans SO_REUSEADDR, les ports utilisés sont invalidés pendant un certain temps (même si aucun processus n écoute sur le port) ce qui peut poser problème pour un serveur.

n°1332240
dounia2
Posté le 25-03-2006 à 18:45:37  profilanswer
 

mais il n y a pas d arguments dans le bind():
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
 
A moins que tu en utilise un autre, moi c'est le seul pour les socket que j ai trouvé.
 
Si c est bien dans celui la que tu mets le flag, tu le mets ou?

n°1332246
nargy
Posté le 25-03-2006 à 19:01:50  profilanswer
 

pardon je suis vraiment à l ouest aujourd hui:
 

Code :
  1. int setsockopt(int s, int  level,  int  optname,  const  void  *optval, socklen_t optlen);

n°1332249
dounia2
Posté le 25-03-2006 à 19:06:28  profilanswer
 

ok je vois , merci pour ton aide :)

mood
Publicité
Posté le   profilanswer
 


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

  Structure sockaddr_in

 

Sujets relatifs
Probleme de taille de structure avec char[] et doubleProbléme de tri et affichage d'élément dans une structure
Probleme tableau 2 dimensions + structure en CTableau de structure
structure if - else (débutant)Structure & Actualisation d'un site ? a votre avis ?
Maintien rapide aisée d'une arborescence : quelle structure choisir ?[Visual MFC] Sérialisation de structure (LOGFONT)...?
Héritage de structure en C/C++?Problème structure de mon site
Plus de sujets relatifs à : Structure sockaddr_in


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)