[英]inet_ntoa() in Winsock2 is deprecated?
我当时正在试验 Winsock2,并收到警告说inet_ntoa()
已被弃用,我应该使用inet_pton()
。 我试过了,但它是小端的,所以保存在缓冲区中的整个字符串是“错误的”。 我猜inet_ntoa()
是大端?
而且我只能将inet_pton()
与#include <ws2tcpip.h>
一起使用,所以对我来说,从这里开始会变得更加混乱。 为什么我应该使用<winsock2.h>
库之外的其他东西?
目前,我通过使用我不喜欢的#pragma warning(disable: 4996)
来避免这种情况,因为我只是不想忽略所有警告。
整个 Winsock 主题对我来说就像一个迷宫,如果我遗漏了一些信息,抱歉,希望这就足够了。
inet_pton()
inet_addr()
inet_ntoa() 的后继者,而是inet_ntoa()
的后继者。 你想要inet_ntop()
代替。
inet_ntoa()
/ inet_ntop()
将 IP 地址从二进制形式转换为字符串形式。 inet_addr( inet_addr()
/ inet_pton()
做相反的转换。
但是,实际上有几个函数可以用来代替inet_ntoa()
,包括getnameinfo()
、 WSAAddressToString()
、 RtlIpv4AddressToString()
/ RtlIpv6AddressToString()
等。
话虽如此,是inet_ntoa()
确实已被弃用,因为它只支持 IPv4 地址。 inet_ntop()
、 getnameinfo()
等函数同时支持 IPv4 和 IPv6 地址,这使得编写 IP 版本无关代码更容易一些。
如果您在使用inet_ntop()
时遇到问题,则说明您使用错误,但没有显示您的代码。 IPv4 地址始终以“网络字节顺序”(大端)的二进制形式表示,即使在小端系统(如 Windows)上也是如此。
至于<ws2tcpip.h>
,它是 Winsock2 库的一部分。 Nothing requires an API to only have 1 header file (indeed, the Win32 API as a whole consists of thousands of header files, beginning with but not limited to <windows.h>
).
处理弃用警告的正确方法是更新代码以使用未弃用的现代 API,就像它希望你那样。 否则,如果此时您不适合这样做,那么至少您可以在受影响的代码上使用#pragma warning(suppress: 4996)
,而不是全局使用#pragma warning(disable: 4996)
。 或者,您可以在项目设置中定义_WINSOCK_DEPRECATED_NO_WARNINGS
,或者您可以在#include
之前在代码中#define
任何 Winsock2 标头。
inet_ntoa()
有几个限制,限制了它在现代世界中的用处。
一方面,它仅适用于 IPv4 地址——如果您需要将 IPv6 地址转换为人类可读的文本,那么就inet_ntoa()
而言,您不走运。
另一个问题是inet_ntoa()
返回一个指向 static 缓冲区的char *
,这是有问题的——如果您不立即将字符串复制到其他地方,则 static 缓冲区的内容可能会被另一个套接字 API 调用覆盖在您阅读之前,这可能是一个难以追踪和修复的运行时错误。 (当多个线程同时调用inet_ntoa()
时,也可能出现竞争条件,尽管微软文档页面的措辞让我怀疑微软可能会返回一个指向线程本地缓冲区的指针以避免这种特殊情况蠕虫)
因此,最佳做法是尽可能避免调用inet_ntoa()
,而改为调用其现代替代品inet_ntop() 。 ( inet_ntop()
使用起来有点困难,但它避免了上面列出的问题)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.