Getting the source address of an incoming socket connection
32,298
Solution 1
You need the getpeername
function:
// 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);
Solution 2
Assuming you're using accept()
to accept incoming socket connections, getpeername()
isn't needed. The address information is available via the 2nd and 3rd parameters of the accept()
call.
Here is Eli's answer modified to do it without 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);
Solution 3
Since you say it is an incoming connection from a client, as an alternative to getpeername
you can just save the address that was returned by the accept()
call, in the second and third parameters.
Author by
Admin
Updated on December 08, 2020Comments
-
Admin over 3 years
I have a server with a incoming socket from a client. I need the get the IP address of the remote client. Tried searching google for
in_addr
but it's a bit troublesome. Any suggestions? -
iammilind almost 10 years+1 for directly using
accept()
. However don't we have to free any memory for this? -
iammilind almost 10 years+1. However don't we have to free any memory for this?
-
Exectron almost 10 years@iammilind: I don't think any memory needs to be freed—I can't see any dynamic allocations being done. It's all done with statically allocated variables.
-
Exectron almost 9 yearsI notice the
struct sockaddr_in *s
shadows the sockets
in the outer scope. Having a shadowed variable isn't ideal. -
Bionix1441 over 7 yearsis there a way to get the socketDescriptor from the address
-
kbridge4096 over 5 years@RecolicKeghart try wayback machine :)
-
recolic over 5 years@brk It works! Please use this link if you're suffering from 404 too.