2010-01-14 16 views
16

İstemciden gelen bir sokete sahip bir sunucum var. Uzak istemcinin IP adresini almalıyım. in_addr için Google'da arama yapmayı denedim, ancak biraz zahmetli. Herhangi bir öneriniz var mı?Gelen soket bağlantısının kaynak adresini alma

+0

in_addr IPv4 özeldir, her neyse – bortzmeyer

+0

linux inet_ntoa (..) işlevine bakın .. 'Adam inet_ntoa'. Benim düşünceme göre inet_ntop daha kolay ve arpa/inet.h dahil olmak üzere ihtiyaçlar. İşte bir örnek: http://www.binarytides.com/programming-udp-sockets-c-linux/ – mhk

cevap

32

getpeername işlevine ihtiyacınız vardır. Büyük Beej'in ağ oluşturma rehberi page about it'a sahiptir. İşte oradan bir kod örneği verilmiştir: Eğer ikinci ve üçte sadece accept() çağrısıyla döndürüldü adresini kaydedebilir getpeername alternatif olarak bir istemciden gelen bağlantı, demek yana

// assume s is a connected socket 

socklen_t len; 
struct sockaddr_storage addr; 
char ipstr[INET6_ADDRSTRLEN]; 
int port; 

len = sizeof addr; 
getpeername(s, (struct sockaddr*)&addr, &len); 

// deal with both IPv4 and IPv6: 
if (addr.ss_family == AF_INET) { 
    struct sockaddr_in *s = (struct sockaddr_in *)&addr; 
    port = ntohs(s->sin_port); 
    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); 
} else { // AF_INET6 
    struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; 
    port = ntohs(s->sin6_port); 
    inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); 
} 

printf("Peer IP address: %s\n", ipstr); 
+0

+1. Ancak bunun için herhangi bir hafızayı boşaltmamız gerekmiyor mu? – iammilind

+1

"struct sockaddr_in * s", dış kapsamdaki soketi 's 'gölgelendiriyor. Gölgeli değişkene sahip olmak ideal değildir. –

+0

'accept() 'ile doğrudan kullanmak için socketDescriptor adresini – Bionix1441

1

parametreleri.

9

Gelen soket bağlantılarını kabul etmek için accept() kullandığınızı varsayarak, getpeername() gerekli değildir. Adres bilgisi, accept() çağrısının 2. ve 3. parametreleri üzerinden kullanılabilir. İşte

Eli cevabı getpeername() olmadan bunu yapmak için değiştirilir:

int client_socket_fd; 
socklen_t len; 
struct sockaddr_storage addr; 
char ipstr[INET6_ADDRSTRLEN]; 
int port; 

len = sizeof addr; 
client_socket_fd = accept(server_socket_fd, (struct sockaddr*)&addr, &len); 

// deal with both IPv4 and IPv6: 
if (addr.ss_family == AF_INET) { 
    struct sockaddr_in *s = (struct sockaddr_in *)&addr; 
    port = ntohs(s->sin_port); 
    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); 
} else { // AF_INET6 
    struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; 
    port = ntohs(s->sin6_port); 
    inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); 
} 

printf("Peer IP address: %s\n", ipstr); 
+0

+1 adresinden almanın bir yolu var. Ancak bunun için herhangi bir hafızayı boşaltmamız gerekmiyor mu? – iammilind

+3

@iammilind: Herhangi bir belleğin boşaltılacağını sanmıyorum - Yapılmakta olan herhangi bir dinamik ayırma göremiyorum. Hepsi statik olarak ayrılmış değişkenlerle yapılır. –

İlgili konular