我有一个sockaddr_storage
对象,我需要用用户提供的值填充它。请注意,用户可以提供AF_INET
或AF_INET6
作为填充结构体的域。
void fill(sockaddr_storage &addrStruct, int domain,
const char addr[], const int port)
{
std::memset(&addrStruct, 0, sizeof(addrStruct));
switch(domain) {
case AF_INET: addrStruct.sin_family = AF_INET;
addrStruct.sin_port= htons(port);
inet_pton(AF_INET, addr, addrStruct.sin_addr);
case AF_INET6: ....
....
....
default: ....
}
}
字符串
很确定这不起作用,因为addrStruct
的类型是struct sockaddr_storage
,而这些成员存在于struct sockaddr_in
中。我也试过static_cast<sockaddr_in>(addrStruct).sin_port
和类似的,但同样不起作用。那么我应该如何填充这个结构体,使它在保持有效值的同时,尊重转换结构体的对齐。
3条答案
按热度按时间wecizke31#
您需要首先使用适当的地址结构,并填写它:
字符串
然后,完成后,将
memcpy()
放入sockaddr_storage
:型
请注意,您仍然应该像以前一样,预先将整个
sockaddr_storage
缓冲区清零。另一种方法是定义所有地址结构的
union
,包括sockaddr_storage
,然后初始化相应的union
成员。wz1wpwve2#
使用getaddrinfo几乎总是比使用
inet_*
系列地址转换函数更好。它会为您完成sockaddr
对象的所有分配和初始化您不必亲自处理sockaddr_storage
。它无缝地处理IPv4和IPv6,它处理具有多个地址的“多宿主”主机,并且它可以(可选地)进行DNS查找。要使用
getaddrinfo
,您完全放弃了所展示的fill
函数。usesfill
的代码可能看起来像这样:字符串
你把它换成
型
这看起来更复杂,但请记住,它完全取代了您不知道如何编写的
fill
函数,并且还记得它将无缝地为您处理DNS。(如果您有具体的理由只想处理数字地址,您可以在hints
中为此设置标志。更详细的示例用法请参阅我链接的手册页。
uoifb46i3#
你必须重新解释
addrStruct
到sockaddr_in
的转换。在你的例子中,代码如下:字符串
但是我建议你使用
getaddrinfo(3)
来代替你的方法。