我正在编写简单的服务器/客户端,并尝试获取客户端的IP地址并将其保存在服务器端,以决定哪个客户端应该进入临界区。我多次搜索了谷歌,但无法找到从sock结构体中获取IP地址的适当方法。
我相信这是在服务器接受客户端请求之后从sock结构体中获取IP的一种方法。更具体地说,在c语言中,当服务器执行
csock = accept(ssock, (struct sockaddr *)&client_addr, &clen)
感谢。我正在编写简单的服务器/客户端,并尝试获取客户端的IP地址并将其保存在服务器端,以决定哪个客户端应该进入临界区。我多次搜索了谷歌,但无法找到从sock结构体中获取IP地址的适当方法。
我相信这是在服务器接受客户端请求之后从sock结构体中获取IP的一种方法。更具体地说,在c语言中,当服务器执行
csock = accept(ssock, (struct sockaddr *)&client_addr, &clen)
感谢。假设您正在使用IPv4,则请执行以下操作:
struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&client_addr;
struct in_addr ipAddr = pV4Addr->sin_addr;
如果你想要将 IP 地址转换为字符串,可以执行以下操作:
char str[INET_ADDRSTRLEN];
inet_ntop( AF_INET, &ipAddr, str, INET_ADDRSTRLEN );
IPv6也相当简单...
struct sockaddr_in6* pV6Addr = (struct sockaddr_in6*)&client_addr;
struct in6_addr ipAddr = pV6Addr->sin6_addr;
获取一个字符串几乎与获取 IPV4 地址相同
char str[INET6_ADDRSTRLEN];
inet_ntop( AF_INET6, &ipAddr, str, INET6_ADDRSTRLEN );
提取IP地址和端口号的更简单和正确的方法如下:
printf("IP address is: %s\n", inet_ntoa(client_addr.sin_addr));
printf("port is: %d\n", (int) ntohs(client_addr.sin_port));
SoapBox的被接受的答案可能不适用于所有架构。参见大端和小端。
假设 client_addr
是一个 struct sockaddr_in
(通常情况下是这样)。您可以从 client_addr.sin_addr.s_addr
中获取 IP 地址(作为一个 32 位无符号整数)。
您可以通过以下方式将其转换为字符串:
printf("%d.%d.%d.%d\n",
int(client.sin_addr.s_addr&0xFF),
int((client.sin_addr.s_addr&0xFF00)>>8),
int((client.sin_addr.s_addr&0xFF0000)>>16),
int((client.sin_addr.s_addr&0xFF000000)>>24));
inet_ntoa
不是线程安全的,虽然它在大多数情况下使用时可能并不重要。一个安全的替代品是 inet_ntop
。 - jweyrich
str
缓冲区传递给inet_ntop()
。而且sin_addr
是一个结构体 - 必须使用sin_addr.s_addr
。值得注意的是,IPv4地址以网络字节顺序存储,并且要将其视为十六进制数,需要使用ntohl(pV4Addr->sin_addr.s_addr)
。 - Dummy00001struct sockaddr_in *
这样的类型中,你不能省略struct
。此外,IPV4方法应该使用struct in_addr
而不是int
来存储地址,类似于你展示的IPV6方法。 - caf