2010-01-14 3 views
16

Ich habe einen Server mit einem eingehenden Socket von einem Client. Ich brauche die IP-Adresse des Remote-Clients. Erprobte Suche nach Google nach in_addr, aber es ist ein bisschen mühsam. Irgendwelche Vorschläge?Abrufen der Quelladresse einer eingehenden Socket-Verbindung

+0

in_addr IPv4-spezifisch ist, sowieso – bortzmeyer

+0

inet_ntoa (..) Funktion in Linux .. 'Mann inet_ntoa' zu sehen. es ist einfacher als inet_ntop meiner Meinung nach und einschließlich arpa/inet.h. Hier ist ein Beispiel: http://www.binarytides.com/programming-udp-sockets-c-linux/ – mhk

Antwort

32

Sie benötigen die getpeername Funktion. Der große Beej's Leitfaden zum Networking hat eine page about it. Hier ist ein Codebeispiel von dort:

// 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. Aber müssen wir dafür keine Speicher frei machen? – iammilind

+1

Ich bemerke, dass 'struct sockaddr_in * s' den Socket' s' im äußeren Bereich schattiert. Eine beschattete Variable ist nicht ideal. –

+0

gibt es eine Möglichkeit, den SocketDescriptor von der Adresse – Bionix1441

1

Da Sie sagen, es ist eine eingehende Verbindung von einem Client, als Alternative zu getpeername Sie können einfach die Adresse speichern, die von dem accept() Aufruf zurückgegeben wurde, in den zweiten und dritten Parameter.

9

Angenommen, Sie verwenden accept(), um eingehende Socket-Verbindungen zu akzeptieren, wird getpeername() nicht benötigt. Die Adressinformation steht über den 2. und 3. Parameter des accept() Aufrufs zur Verfügung.

Hier ist die Antwort von Eli geändert, es zu tun, ohne getpeername():

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 für die direkte Verwendung von 'accept()' zu erhalten. Aber müssen wir dafür keine Speicher frei machen? – iammilind

+3

@iammilind: Ich denke nicht, dass irgendwelche Speicher freigegeben werden müssen - ich kann keine dynamischen Zuordnungen sehen. Es ist alles mit statisch zugewiesenen Variablen getan. –

Verwandte Themen