2012-10-10 38 views
7

Actualmente estoy trabajando en un servidor UDP que recibe una solicitud de un cliente. El datagrama que recibo es una matriz de bytes (caracteres) de 5 elementos de longitud, con los dos elementos finales como un número de puerto.Extrayendo la dirección IP y la información del puerto de sockaddr_storage

Eventualmente este servidor tendrá que devolver tanto la dirección IP como el número de puerto en un datagrama propio.

Ya sé cómo usar inet_ntop y la estructura de sockaddr con la que me he conectado y recibido para imprimir la ip, pero devuelve una cadena que no está en el formato que quiero. Por ejemplo:

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

devuelve:

127.0.0.1 

o:

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

cuando necesito algo como:

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

debo utilizar algún tipo de carácter y manipulación de matriz para hacer mi byte de 4 elementos e matriz? ¿O una sockaddr tiene esta información de manera que puedo dejarla en esta forma hexadecimal y devolverla?

Respuesta

12

Asumiendo para IPv4.

Después de tomar la dirección de su estructura sockaddr_storage o sockaddr y lanzarlo a la versión IPv4 sockaddr_in, a continuación, puede acceder a los bytes individuales de la dirección IPv4.

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

Entonces usted puede tomar la dirección del miembro s_addr que es un valor de 32 bits (in_addr_t) que contiene los 4 bytes de la dirección IP (en orden de bytes de red), y echarlo a un puntero a un unsigned char cuales luego le permite acceder a los bytes individuales del valor.

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

Esto es exactamente lo que estaba buscando. Conciso y excelente. Gracias @Kludas – Ryanman

5

que desea utilizar probablemente getnameinfo() función:

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

ej .:

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); 
Cuestiones relacionadas