2012-10-10 9 views
7

Attualmente sto lavorando su un server UDP che riceve una richiesta da un client. Il datagramma che ricevo è un array di byte (char) lungo 5 elementi, con gli ultimi due elementi che sono un numero di porta.Estrazione dell'indirizzo IP e delle informazioni sulla porta da sockaddr_storage

Alla fine questo server dovrà restituire sia l'indirizzo IP che il numero di porta in un proprio datagramma.

So già come utilizzare inet_ntop e la struttura sockaddr con cui mi sono connesso e ricevuto per stampare l'ip, ma restituisce una stringa che non è nel formato che desidero. Per esempio:

string1 = inet_ntop(their_addr.ss_family,get_in_addr(
    (struct sockaddr *)&their_addr),s, sizeof s); 

rendimenti:

127.0.0.1 

o:

[1][2][7][.][0][.][0][.][1] 

quando ho bisogno di qualcosa di simile a:

[127][0][0][1] 

Dovrei usare un qualche tipo di carattere e manipolazione di array per rendere il mio 4-elemento byt e array? O un sockaddr ha questa informazione in modo che io possa lasciarla in questa forma esadecimale e restituirla?

risposta

12

Presupposto per IPv4.

Dopo aver preso l'indirizzo del vostro sockaddr_storage o sockaddr struttura e il cast per la versione IPv4 sockaddr_in, è quindi possibile accedere ai singoli byte dell'indirizzo IPv4.

struct sockaddr_in *sin = (struct sockaddr_in *)&their_addr; 

Poi si può prendere indirizzo del membro s_addr che è un valore a 32 bit (in_addr_t) che contiene i 4 byte dell'indirizzo IP (in ordine di byte di rete) e il cast a un puntatore ad un unsigned char che quindi ti consente di accedere ai singoli byte del valore.

unsigned char *ip = (unsigned char *)&sin->sin_addr.s_addr; 

printf("%d %d %d %d\n", ip[0], ip[1], ip[2], ip[3]); 
+0

Questo è esattamente quello che stavo cercando. Conciso ed eccellente. Grazie @ Kludi – Ryanman

5

si desidera utilizzare probabilmente getnameinfo() funzione:

int getnameinfo(const struct sockaddr *sa, socklen_t salen, 
        char *host, size_t hostlen, 
        char *serv, size_t servlen, int flags); 

Es .:

struct sockaddr_storage client_addr; 
socklen_t client_len = sizeof(struct sockaddr_storage); 

/* Accept client request */ 
int client_socket = accept(server_socket, 
    (struct sockaddr *)&client_addr, &client_len); 

char hoststr[NI_MAXHOST]; 
char portstr[NI_MAXSERV]; 

int rc = getnameinfo((struct sockaddr *)&client_addr, 
    client_len, hoststr, sizeof(hoststr), portstr, sizeof(portstr), 
    NI_NUMERICHOST | NI_NUMERICSERV); 

if (rc == 0) 
    printf("New connection from %s %s", hoststr, portstr); 
Problemi correlati