获取传入套接字连接的源地址

时间:2010-01-14 14:15:10

标签: c sockets ip

我有一个服务器,它有来自客户端的传入套接字。 我需要获取远程客户端的IP地址。 尝试搜索谷歌in_addr,但它有点麻烦。 有什么建议吗?

3 个答案:

答案 0 :(得分:35)

您需要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);

答案 1 :(得分:15)

假设您使用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);

答案 2 :(得分:2)

由于您说它是来自客户端的传入连接,因此作为getpeername的替代,您可以在第二个和第三个参数中保存accept()调用返回的地址。< / p>