Newsgroup: it.comp.os.linux.development
Titolo: Problema Semplice sui socket

Salve a tutti,
ho un problema apparentemente semplice da risolvere , ma non ci
riesco. Un server Accetta una connessione su di un certo socket, mediante
temp_sock_descriptor =
    accept(sock_descriptor, (struct sockaddr *)&pin,&address_size);
la struttura pin , di tipo " struct sockaddr_in"
viene automaticamente riempita con i dati del client. Dove posso
trovare in questa struttura l'indirizzo IP del client ?
ho provato a leggere /usr/include/socket.h ma non ci capisco un gran
che'.
Ps. Dovrebbe essere qualcosa tipo pin.sin_addr.s_addr, ma mi risulta un 
valore nullo.
-- 
---- > Davide Patti <--------------------
 

Davide Patti wrote:

Vediamo di capirci qualcosa con calma.
Prima di tutto l'header da te citato non è quello in cui devi andare a 
curiosare (anche perchè a dirla tutta /usr/include/socket.h non esiste!)
ma devi vedere /usr/include/netinet/in.h.Qui a un certo punto trovi
/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };
[..]
/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;                 /* Port number.  */
    struct in_addr sin_addr;            /* Internet address.  */
    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) -
                           __SOCKADDR_COMMON_SIZE -
                           sizeof (in_port_t) -
                           sizeof (struct in_addr)];
  };
Non ti serve capire tutto ma come puoi vedere nella sockaddr_in è definita 
sin_addr che è una struct in_addr.Questa struct contiene un solo field (se 
ti chiedi a che serva una struct con un solo field ti posso dire che questo 
dipende da motivi di compatibilità con 4.2BSD in cui la in_addr era 
definita come union per consentire l'accesso a ciascuno dei 4 bytes 
dell'indirizzo IP).Ora chiarito questo (sai penso che bisogna prima di 
tutto aver chiaro che cosa si stia maneggiando piuttosto che attaccare due 
righe di codice che potrebbero non significare nulla per te ma che 
funzionano) tu vuoi visualizzare l'indirizzo del client.Devi considerare 
un'ultima cosa.Nella sockaddr_in gli indirizzi vengono inseriti in network 
byte order il che significa che devi parsarli (che brutta parola che ho 
detto :) ).La maniera più semplice è usare la inet_ntop (a questo punto un 
`man inet_ntop` male non ci starebbe!) in questo modo 
temp_sock_descriptor =
     accept(sock_descriptor, (struct sockaddr *)&pin,&address_size);
printf("connection from %s",                                            
inet_ntop(AF_INET,&pin.sin_addr,buffer,sizeof(buffer)));
avendo dichiarato in precedenza buffer come
char buffer[ADDRESS_SIZE];
Spero ti sia tutto chiaro.In caso contrario chiedi pure.
Alla prossima!
Angelo Dell'Aera

 
Sei stato gentilissimo, 
adesso ho capito molto meglio come stanno le cose. Adesso funziona tutto 
correttamente , quando il client si trova su di una altra macchina 
l'indirizzo viene riconosciuto. Quando pero' faccio la connessione dalla 
stessa macchina dove sta il server l'indirizzo IP del client risulta 
0.0.0.0 , e' normale che sia cosi' ? 


Davide Patti wrote:

Non è propriamente normale che accada.Guarda qui.Per l'occasione ho scritto 
un banalissimo client e un server daytime.Ti mostro gli output.
lato client:
bash-2.05$ ./client 127.0.0.1
Thu Jan 10 16:25:55 2002
lato server:
root@darkstar:/usr/src/unp# ./server 
Connection from : 127.0.0.1
Sei sicuro di non aver commesso qualche errorino? O in alternativa..sei 
sicuro di non aver `giocato in maniera spregiudicata' con il wildcard IP 
address INADDR_ANY? Posta il codice che magari gli diamo un'occhiata!
Alla prossima,
Angelo Dell'Aera

 address INADDR_ANY? Posta il codice che magari gli diamo un'occhiata!
Ho inizializzato
    bzero(&sin, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons(port);
    e poi ho usato :
bind(sock_descriptor, (struct sockaddr *)&sin, sizeof(sin));
etc .etc...
temp_sock_descriptor =
      accept(sock_descriptor, (struct sockaddr *)&pin,&address_size);
e ho visualizzato l'indirizzo come da te consigliato :
printf(" indirizzzo : 
%s\n",inet_ntop(AF_INET,&pin.sin_addr,client_ip,sizeof(client_ip)));
avendo definito : char client_ip[INET_ADDRSTRLEN];
Perche' a volte mi spunta l'indirizzo client come 0.0.0.0 ??
