![](/img/trans.png)
[英]WinSock c++ inet_ntop always displays 204.204.204.204 (and accept() didn't failed)
[英]Difficulty understanding second parameter of inet_ntop() in C++
我正在尝试根据此处提供的教程在C ++中创建一个基本的Web服务器:
https://vichargrave.github.io/articles/2013-02/tcp-ip-network-programming-design-patterns-in-cpp
并且在理解以下行时遇到麻烦:
inet_ntop(PF_INET, (struct in_addr*)&(address->sin_addr.s_addr), ip, sizeof(ip)-1);
具体来说,我在理解第二个参数时遇到了麻烦:
(struct in_addr*)&(address->sin_addr.s_addr)
是在做。 该参数是一种我以前从未见过的语法,基于我所知道的它在做以下两件事之一:
它是将struct in_addr
指针与地址中的给定字段进行“与” in_addr
它正在将address->sin_addr.s_addr
的地址转换为struct in_addr*
的指针
哪一个?
编辑:所以看来这是演员。 这使我想到另一个问题。 该参数似乎将in_addr_t
类型的变量in_addr_t
转换为没有意义的结构。 这是对它的正确看法还是在做其他事情?
另外,我参考以下页面以获取有关此功能的文档:
http://pubs.opengroup.org/onlinepubs/7908799/xns/netinetin.h.html http://pubs.opengroup.org/onlinepubs/009695399/functions/inet_ntop.html
为了更好地理解,请从右向左阅读。
(struct in_addr*)&(address->sin_addr.s_addr)
所以,
address->sin_addr.s_addr --> uses the "address" ptr to access sin_addr.s_addr
然后
&(address->sin_addr.s_addr) takes the address of s_addr.
然后
(struct in_addr*) casts the address taken by & to in_addr.
以上是有意义的,因为在这种情况下以下2是等效的
(struct in_addr*)&(address->sin_addr.s_addr)
(struct in_addr*)&(address->sin_addr)
结构的地址与C / C ++中其第一个成员的地址相同。
要回答你的第一个问题,它确实是铸造的地址 address->sin_addr.s_addr
领域的struct in_addr*
指针。 由于该问题被标记为c++
,因此C ++样式转换将使这一点更加清晰:
inet_ntop(PF_INET, reinterpret_cast<struct in_addr*>(&(address->sin_addr.s_addr)), ip, sizeof(ip)-1);
要回答第二个问题,它不是将变量本身强制转换为指针。 它将变量的地址转换为其他指针类型。 在这种情况下, s_addr
字段的地址被s_addr
转换为struct in_addr*
指针。 类型的第一个字段的地址与类型本身的地址相同。 因此,将s_addr
的地址 s_addr
为struct in_addr*
是安全的。
但是,话说回来,演员表是多余的 ,应该删除。 inet_ntop()
的第二个参数是const void*
,任何指针都可以按原样分配给void*
。 当第一个参数是(AF|PF)_INET
,第二个参数必须是指向struct in_addr
的指针,因此您应该使用sin_addr
字段本身(实际上是in_addr
)的地址,而不是其s_addr
字段(即in_addr
内的字段):
inet_ntop(AF_INET, &(address->sin_addr), ip, sizeof(ip)-1);
如果您具有IPv6地址(第一个参数是(AF|PF)_INET6
),则第二个参数必须是指向struct in6_addr
的指针,该指针将是sockaddr_in6
的sin6_addr
字段:
inet_ntop(AF_INET6, &(address->sin6_addr), ip, sizeof(ip)-1);
为了支持这两个家族(首先使用inet_ntop()
主要原因), address
应该是指向struct sockaddr_storage
的指针(该指针足以容纳任何struct sockaddr_...
类型,但在这种情况下为IPv4和IPv6地址),并且ip
必须至少为46个字符(最好使用INET6_ADDRSTRLEN
定义的字符)。 然后,您可以执行以下操作:
switch (address->ss_family)
{
case AF_INET:
inet_ntop(AF_INET, &(reinterpret_cast<struct sockaddr_in*>(address)->sin_addr), ip, sizeof(ip)-1);
break;
case AF_INET6:
inet_ntop(AF_INET6, &(reinterpret_cast<struct sockaddr_in6*>(address)->sin6_addr), ip, sizeof(ip)-1);
break;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.