2012-10-10 15 views
7

Şu anda bir istemciden istek alan bir UDP sunucusunda çalışıyorum. Aldığım datagram, 5 eleman uzunluğunda bir bayt (char) dizisidir ve son iki eleman bir port numarasıdır.Sockaddr_storage öğesinden IP Adresi ve Bağlantı Noktası Bilgisi ayıklanıyor

Sonunda bu sunucu, kendi IP adres ve port numaralarını kendi başına bir datagrama geri göndermelidir.

IP'yi yazdırmak için bağlandığım ve aldığım inet_ntop ve sockaddr yapısını nasıl kullanacağımı biliyorum, ancak istediğim biçimde olmayan bir dize döndürüyor.

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

döner:

127.0.0.1 

ya:

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

Karakterin çeşit kullanarak ve olmalı:

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

gibi bir şey gerekir Mesela 4 elementli byt'ım yapmak için dizi manipülasyon e dizi? Ya da bir sockaddr bu bilgiyi, bu onaltılık formda bırakıp geri verebileceğim bir şekilde var mı? IPv4 için varsayarsak

cevap

12

.

sizin sockaddr_storage veya sockaddr yapının adresini alıp IPv4 sürümü sockaddr_in bunu attıktan sonra, daha sonra IPv4 adresinin tek tek bayt erişebilirler.

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

Sonra (ağ bayt sırasına göre) ip adresinin 4 bayt tutan bir 32 bitlik değer (in_addr_t) 'dir s_addr üyesinin adresini almak ve bir unsigned char için bir işaretçi yayınlayabilmek için hangi daha sonra, değerin tek tek baytlarına erişmenizi sağlar. Bu benim aradığım tam olarak ne olduğunu

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

Örn .:

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); 
+0

:

unsigned char *ip = (unsigned char *)&sin->sin_addr.s_addr; printf("%d %d %d %d\n", ip[0], ip[1], ip[2], ip[3]); 
Ryanman

5

Muhtemelen getnameinfo() fonksiyonunu kullanmak istiyorum. Özlü ve mükemmel. Teşekkürler @Kludas
İlgili konular