C++ Winsock2中的inet_ntoa()已被弃用?

C++ Winsock2中的inet_ntoa()已被弃用?,c++,winsock,winsock2,C++,Winsock,Winsock2,我当时正在试验Winsock2,收到了一条警告,inet\u ntoa()已被弃用,我应该使用inet\u pton()。我试过了,但它是little endian,所以保存在缓冲区中的整个字符串都是“错误的”。我猜inet\u ntoa()是big-endian吗 我只能将inet\u pton()与#include一起使用,所以对我来说,从现在开始,它会变得更加混乱。为什么要使用库之外的其他内容 目前,我通过使用#pragma warning(disable:4996)来避免这种情况,我不喜

我当时正在试验Winsock2,收到了一条警告,
inet\u ntoa()
已被弃用,我应该使用
inet\u pton()
。我试过了,但它是little endian,所以保存在缓冲区中的整个字符串都是“错误的”。我猜
inet\u ntoa()
是big-endian吗

我只能将
inet\u pton()
#include
一起使用,所以对我来说,从现在开始,它会变得更加混乱。为什么要使用
库之外的其他内容

目前,我通过使用
#pragma warning(disable:4996)
来避免这种情况,我不喜欢这样,因为我只是不想忽略所有警告

整个Winsock主题对我来说就像一个迷宫,如果我遗漏了一些信息,很抱歉,希望这足够了。

inet\u pton()
不是
inet\u ntoa()
的继承者,而是
inet\u addr()
的继承者。你想要的是

inet\u ntoa()
/
inet\u ntop()
将IP地址从二进制形式转换为字符串形式
inet\u addr()
/
inet\u pton()
执行相反的转换

但是,实际上有几个函数可以用来代替inet\u ntoa(),包括,/,等等

也就是说,yes
inet\u ntoa()
确实不受欢迎,因为它只支持IPv4地址。像
inet\u ntop()
getnameinfo()
等函数都支持IPv4和IPv6地址,这使得编写IP版本无关的代码更容易一些

如果您在使用
inet\u ntop()
时遇到问题,则说明您使用错误,但没有显示代码。IPv4地址总是以“网络字节顺序”(大端)的二进制形式表示,即使在像Windows这样的小端系统上也是如此

至于
,它是Winsock2库的一部分。没有什么要求一个API只有一个头文件(实际上,Win32 API作为一个整体由数千个头文件组成,首先是但不限于

处理弃用警告的正确方法是更新代码,使其使用一个现代API,而不是像它希望您使用的那样弃用。否则,如果此时您不能选择此选项,则至少可以仅对受影响的代码使用
#pragma warning(suppress:4996)
,而不是全局使用
#pragma warning(disable:4996)
。或者,您可以在项目设置中定义
\u WINSOCK\u DEPRECATED\u NO\u WARNINGS
,或者您可以在
之前在代码中定义
,包括
”任何Winsock2头。

inet\u ntoa()
有一些限制,限制了它在现代世界中的用途

首先,它只适用于IPv4地址——如果您需要将IPv6地址转换为人类可读的文本,那么就
inet\u ntoa()
而言,您就不走运了

另一个问题是
inet\u ntoa()
返回指向静态缓冲区的
char*
,这是有问题的——如果不立即将字符串复制到其他地方,则在读取之前,静态缓冲区的内容可能会被另一个套接字API调用覆盖,这可能是一个难以追踪和修复的运行时错误。(当多个线程同时调用
inet\u ntoa()
时,也可能存在争用条件,尽管Microsoft的措辞让我怀疑Microsoft可能会返回指向线程本地缓冲区的指针以避免特定的蠕虫)


因此,最好的做法是尽可能避免调用
inet\u ntoa()
,而是调用它的现代替代品。(
inet\u ntop()
使用起来有点困难,但它避免了上面列出的问题)

是的,
inet\u ntoa()
使用线程本地缓冲区,因此在多个线程中并发调用是安全的。但是你是对的,应该使用一个更现代的函数来代替用户提供的缓冲区。谢谢你提供的信息!非常感谢你的解释!这正是我所需要的,我通过谷歌搜索找到了一些教程,更深入地研究了函数本身,但微软文档一点帮助都没有。再次感谢你为我节省了一天的谷歌搜索时间。上一次更新,出于某种原因,我认为是SOCKADDR_IN,但那是在SOCKADDR_IN内,它的工作原理与预期一致,我只是输入了错误的信息。关闭…@cpnuub我想你指的是,对吧?正是因为如此,我才发布了这个链接,在那里你可以看到唯一的IN_ADDR变量是“sin_ADDR”