如何从c中的sock结构中获取IP地址?
Posted
技术标签:
【中文标题】如何从c中的sock结构中获取IP地址?【英文标题】:How to get ip address from sock structure in c? 【发布时间】:2011-03-04 21:47:33 【问题描述】:我正在编写简单的服务器/客户端并尝试获取客户端 IP 地址并将其保存在服务器端以决定哪个客户端应该进入关键部分。我用谷歌搜索了几次,但找不到从 sock 结构中获取 IP 地址的正确方法。
我相信这是一种在服务器接受来自客户端的请求后从 sock 结构中获取 IP 的方法。更具体地说,在服务器执行后的 c 中
csock = accept(ssock, (struct sockaddr *)&client_addr, &clen)
谢谢
【问题讨论】:
【参考方案1】:好的,假设您使用的是 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 );
【讨论】:
您忘记将str
缓冲区传递给inet_ntop()
。而sin_addr
是一个结构——必须使用sin_addr.s_addr
。值得注意的是,IPv4 地址以网络字节顺序存储,要将其视为十六进制数字,需要使用 ntohl(pV4Addr->sin_addr.s_addr)
。
点数......你也错过了我不使用小写字母“in6_addr”;)在 ntohl 前面,我不经常打扰,因为我仍然可以进行相等检查(前提是两者都按网络顺序) 并且它会破坏 inet_ntop(不是吗?)。
这个问题被标记为 C - 你不能在 struct sockaddr_in *
这样的类型中省略 struct
。此外,IPV4 方法应使用struct in_addr
而不是int
来存储地址,类似于您显示的 IPV6 方法。【参考方案2】:
提取 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 接受的答案并不适用于所有架构。见Big and Little Endian。
【讨论】:
【参考方案3】:假设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_ntoa
不是线程安全的,尽管在大多数使用它的情况下这可能并不重要。一个安全的替代方案是inet_ntop
。
@RemyLebeau 又好又简单。我喜欢它。以上是关于如何从c中的sock结构中获取IP地址?的主要内容,如果未能解决你的问题,请参考以下文章