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

Dav*_*vid 19 c sockets ip

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

Eli*_*sky 37

你需要这个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);
Run Code Online (Sandbox Code Playgroud)

  • 我注意到 `struct sockaddr_in *s` 遮蔽了外部作用域中的套接字 `s`。有一个阴影变量并不理想。 (3认同)

Cra*_*een 16

假设您正在使用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);
Run Code Online (Sandbox Code Playgroud)

  • @iammilind:我认为不需要释放任何内存 - 我看不到任何动态分配.这一切都是通过静态分配的变量完成的. (4认同)