Получение адреса источника входящего сокета - PullRequest
18 голосов
/ 14 января 2010

У меня есть сервер с входящим сокетом от клиента. Мне нужно получить IP-адрес удаленного клиента. Попытка поиска в Google для in_addr, но это немного хлопотно. Есть предложения?

Ответы [ 3 ]

35 голосов
/ 14 января 2010

Вам нужна функция getpeername :

// 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);
16 голосов
/ 10 апреля 2014

Если вы используете accept() для приема входящих соединений сокетов, getpeername() не требуется. Информация об адресе доступна через 2-й и 3-й параметры вызова accept().

Вот ответ Элая, модифицированный, чтобы сделать это без 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);
2 голосов
/ 15 января 2010

Поскольку вы говорите, что это входящее соединение от клиента, в качестве альтернативы getpeername вы можете просто сохранить адрес, который был возвращен вызовом accept(), во втором и третьем параметрах.

...