21

クライアントからの着信ソケットを持つサーバーがあります。リモート クライアントの IP アドレスを取得する必要があります。グーグルで検索してみましin_addrたが、ちょっと面倒です。助言がありますか?

4

3 に答える 3

39

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);
于 2010-01-14T14:34:29.040 に答える
19

accept()着信ソケット接続を受け入れるために使用していると仮定すると、getpeername()必要ありません。アドレス情報は、accept()呼び出しの 2 番目と 3 番目のパラメーターを介して利用できます。

なしでそれを行うように変更されたEliの回答は次の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);
于 2014-04-10T01:05:48.167 に答える
2

クライアントからの着信接続であると言うので、代わりに、呼び出しgetpeernameによって返されたアドレスを 2 番目と 3 番目のパラメーターに保存することができます。accept()

于 2010-01-14T23:11:55.670 に答える