了解INADDR_ANY进行套接字编程


84

我正在尝试编程一些套接字,因此在服务器端,我使用htonl(INADDR_ANY)。就我所知,在我看来,该功能会生成一个随机IP(我正确吗?)。实际上,我想将套接字与绑定localhost。但是如果我运行这个

printf("%d",htonl(INADDR_ANY));

我得到0作为返回值。有人可以带来一些解释吗?


9
……我用htonl(INADDR_ANY)。医生说这个功能会产生一个随机IP…… ”这是不正确的。哪个文档告诉您?
ALK

1
@alk,实际上我误导了:我正在阅读一些pdf文件,我认为这是一些官方文档。我现在编辑我的帖子
2013年

Answers:


132
  1. bind()INADDR_ANY的确不是“随机生成一个IP”。它将套接字绑定到所有可用接口

  2. 对于服务器,通常需要绑定到所有接口-而不仅仅是“ localhost”。

  3. 如果您只想将套接字绑定到localhost,则语法为my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");,然后调用bind(my_socket, (SOCKADDR *) &my_sockaddr, ...)

  4. 碰巧INADDR_ANY是一个等于“零”的常数:

    http://www.castaglia.org/proftpd/doc/devel-guide/src/include/inet.h.html

    # define INADDR_ANY ((unsigned long int) 0x00000000)
    ...
    # define INADDR_NONE    0xffffffff
    ...
    # define INPORT_ANY 0
    ...
    
  5. 如果您还不熟悉它,我敦促您查看Beej的套接字编程指南:

    http://beej.us/guide/bgnet/

由于人们仍在阅读此内容,因此请注意:

人(7)ip

当进程想要接收新的传入数据包或连接时,应使用bind(2)将套接字绑定到本地接口地址。

在这种情况下,只有一个IP套接字可以绑定到任何给定的本地(地址,端口)对。在bind调用中指定INADDR_ANY时,套接字将绑定到所有本地接口。

在未绑定的套接字上调用listen(2)时,该套接字会自动绑定到本地地址设置为INADDR_ANY的随机空闲端口。

在未绑定的套接字上调用connect(2)时,套接字会自动绑定到随机空闲端口或本地地址设置为INADDR_ANY的可用共享端口上。

有几个特殊地址:INADDR_LOOPBACK(127.0.0.1)始终通过环回设备引用本地主机;INADDR_ANY(0.0.0.0)表示任何要绑定的地址...

也:

bind()—将名称绑定到套接字

如果(sin_addr.s_addr)字段设置为常数INADDR_ANY(如netinet / in.h中所定义),则调用者正在请求将套接字绑定到主机上的所有网络接口。随后,来自所有接口(与绑定名称匹配)的UDP数据包和TCP连接被路由到应用程序。当服务器为多个网络提供服务时,这一点变得很重要。通过不指定地址,服务器可以接受为其端口发出的所有UDP数据包和TCP连接请求,而不管请求到达的网络接口如何。


4
这并不意味着“绑定到所有接口”。如果这样做,netstat的输出将有所不同。这意味着“在任何界面上收听”。
,洛恩侯爵

6
引用上面的链接:“在bind调用中指定INADDR_ANY时,套接字将绑定到所有本地接口。” 从另一个链接:值“ INADDR_ANY”表示我们将绑定到本地计算机当前具有的任何/所有IP地址。但是,是的-许多实现将绑定到第一个接口(不是“全部”)。但是对于一台带有一个NIC的PC来说,差别是学术上的。使用INADDR_ANY,客户端可以连接到任何/所有IP(例如192.168.1.2和127.0.0.1)。
paulsm4

5
抱歉,这是一个愚蠢的问题,但是接口是否意味着无线,以太网等?
mrQWERTY

3
@ laike9m如果只想从本地计算机连接到套接字,则可以绑定到127.0.0.1。当套接字提供的服务仅打算由机器本地的另一个进程使用时,有一些用例。
dgnuff

2
@ paulsm4在3中,您不能使用INADDR_LOOPBACK代替inet_addr("127.0.0.1")吗?
John Strood

62

INADDR_ANY当您不需要将套接字绑定到特定IP时使用。当您使用该值作为调用时的地址时bind(),套接字会接受与计算机所有IP的连接。


8

要将套接字与localhost绑定,在调用绑定函数之前,应正确设置sockaddr_in结构的sin_addr.s_addr字段。可以通过以下方式获得适当的值:

my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1")

my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);

4

INADDR_ANY指示侦听套接字绑定到所有可用接口。等同于尝试绑定到inet_addr("0.0.0.0")。为了完整起见,我还要提到还有IPv6的IN6ADDR_ANY_INIT,它与尝试绑定到::IPv6套接字的地址相同。

#include <netinet/in.h>

struct in6_addr addr = IN6ADDR_ANY_INIT;

另外,请注意,将IPv6套接字IN6ADDR_ANY_INIT绑定到套接字时,它将绑定到所有IPv6接口,并且还应该能够接受来自IPv4客户端的连接(尽管映射了IPv6的地址)。


2

INADDR_ANY是一个常量,其值包含0。仅当您希望从所有不在意ip-add的活动端口进行连接时,才使用此选项。因此,如果您要连接任何特定的IP,则应提及my_sockaddress.sin_addr.s_addr = inet_addr(“ 192.168.78.2”)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.