c++ - 如何用 getaddrinfo 替换 inet_pton
问题描述
考虑 inet_pton 函数:
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst)
据我了解,该函数以点分十进制形式的IP地址字符串作为输入(src)并将该字符串转换为字节形式,这是某些网络编程任务所必需的。事实上, src 被转换为一个结构 in_addr,它被复制到 dst(假设 af = AF_INET)。在这个结构中,应该有一个字节形式的 IP 地址条目(如果我错了,请纠正我!)。
我希望能够使用 inet_pton,但不是以点分十进制形式提供 src,而是想提供一个可以由我的 DNS 服务器解析的名称。
示例:而不是inet_pton(AF_INET, "10.70.1.114", buf)
我想使用inet_pton(AF_INET, "myPC", buf)
我在想,也许我可以用getaddrinfo
and getnameinfo
before 来解析我的名字。我正在考虑这样的功能:
char* resolvename(const char* name)
{
struct addrinfo *infoptr, hints;
char host[256];
hints.ai_family=AF_INET;
int result = getaddrinfo(name,NULL,&hints,&infoptr);
if(result){
fprintf(stderr, "getaddrinfo: %s\n", gai_stderror(result));
exit(1);
}
getnameinfo(infoptr->ai_addr, infoptr->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
return host;
}
然后我应该能够这样做:
mySrc = resolvename("myPC");
inet_pton(AF_INET, mySrc, buf);
这有任何意义吗?只是说:我没有任何网络编程经验。所有这些功能对我来说都很新,所以请赐教!
解决方案
char host[256]; ... return host;
您返回指向自动数组的指针。该数组在作用域结束时自动销毁,因此您返回一个悬空指针。通过悬空指针间接的行为是未定义的。
此外,由于调用失败freeaddrinfo
,您会泄漏内存。
getaddrinfo
返回 的列表sockaddr
,其中已经包含字节形式的 IP。如何将其取出的示例:
for (; infoptr; infoptr = infoptr->ai_next) {
if (infoptr->ai_family == AF_INET) {
assert(infoptr->ai_addrlen == sizeof(sockaddr_in));
sockaddr_in addr;
std::memcpy(&addr, infoptr->ai_addr, sizeof addr);
std::memcpy(buf, addr.sin_addr, sizeof addr.sin_addr);
break;
}
}
如果您非常聪明,理论上可能有一种方法可以使用 offsetof 摆脱中间 memcpy 到 local sockaddr_in
。
推荐阅读
- wordpress - 如何在我的电子商务网站上重置类别中的问题?
- bootstrap-4 - 当我点击菜单时如何显示下拉菜单
- gradle - 如何引用 gradle.properties 文件中的值
- intellij-idea - IntelliJ 代码覆盖率:如何知道哪些单元测试覆盖了源代码中的行
- c++ - 从现有安装创建 Cmake 包
- flutter - 如何在颤动的蓝牙打印机中设置格式
- python - 使用 fontForge 检查字体文件中缺失的字形
- vba - 处理调用 Access VBA 中的“在 Microsoft Access 之外没有响应应用程序”错误
- java - 验证期间出现 NotReadablePropertyException (Spring Boot)
- salesforce - 如何从 Salesforce LWC 中的另一个组件刷新一个组件?