了解INADDR_ANY以进行套接字编程

eps*_*nes 73 c sockets

我正在尝试编写一些套接字,因此,在服务器端,我使用htonl(INADDR_ANY).在我理解的范围内,在我看来,这个函数生成一个随机IP(我是否正确?).事实上,我想用我的套接字绑定我的套接字localhost.但如果我跑这个

printf("%d",htonl(INADDR_ANY));
Run Code Online (Sandbox Code Playgroud)

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

pau*_*sm4 105

  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
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  5. 如果您还不熟悉它,我建议您查看Beej的套接字编程指南:

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

由于人们还在读这篇文章,还需要补充一点:

男人(7)ip:

当一个进程想要接收新传入的数据包或连接,它应该使用套接字绑定到一个本地接口地址绑定(2) .

在这种情况下,只有一个IP套接字可以绑定到任何给定的本地(地址,端口)对.在绑定调用中指定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连接请求,而不管请求到达的网络接口.

  • 引用上面的链接:"当在bind调用中指定INADDR_ANY时,套接字将绑定到所有本地接口." 从另一个链接:[值"INADDR_ANY"表示我们将绑定到本地计算机当前拥有的任何/所有IP地址](http://www.scottklement.com/rpg/socktut/bindapi.html).但是 - 是的 - 许多实现将绑定到*第一个*接口,(而不是"全部").但对于一台带有一个NIC的PC来说,不同之处在于学术性.使用INADDR_ANY,客户端可以连接到任何/所有IP(例如192.168.1.2和127.0.0.1). (5认同)
  • 对不起,如果这是一个愚蠢的问题,但接口是否意味着无线,以太网等? (5认同)
  • 它并不意味着"绑定到所有接口".如果它这样做,netstat输出将是不同的.这意味着'听*任何*接口'. (4认同)
  • @ laike9m如果希望只能从本地计算机连接到套接字,则绑定到127.0.0.1.当套接字提供的服务仅供机器本地的另一个进程使用时,有用例. (2认同)
  • @ paulsm4 3,你不能使用`INADDR_LOOPBACK`,而不是`inet_addr("127.0.0.1")`? (2认同)

Bar*_*mar 58

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


小智 7

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

my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1")
Run Code Online (Sandbox Code Playgroud)

或者

my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
Run Code Online (Sandbox Code Playgroud)


Lew*_*sey 7

当您拥有服务器时,您可以创建一个套接字,然后将其绑定到 IP 和端口,这为套接字提供了一种基于唯一套接字类型、地址族、IP 和端口来识别的独特方式。然后,你使用listen()将套接字设置为服务器模式,然后执行accept(),它等待一个连接,该连接将有带有目标IP/端口的入站数据包,导致数据包在该套接字上排队。但是,您不需要将其绑定到 IP,它可以接受所有接口上的连接。

当你有一个客户端时,你创建一个套接字,然后将套接字连接到远程 IP 和端口,这也会将 0.0.0.0 和一个随机未使用的临时端口绑定到套接字(如果尚未绑定)使用bind(INADDR_ANY, 0) 到IP 和端口。connect() 在连接时返回,并使用 IP 和端口作为出站数据包中的源地址,其中 0.0.0.0 始终替换为基于路由表中的 src 提示的 IP 或所选接口的 IP(如果它有多个IP,然后选择第一个具有相同或更大范围的IP),然后使用sendall发送应用程序数据。

INADDR_ANY 比以编程方式获取接口的当前内部 IP 更快,后者可能随时更改,并且端口上将不再接收数据包,但仍会在 0.0.0.0 上接收它们,因为它是任何地址。

请注意,套接字可以绑定到 0.0.0.0,但不能绑定到端口 0,因为它是一个通配符,可以为套接字提供随机临时端口,因此当您使用 bind(INADDR_ANY, 0) 时,它会绑定到 0.0.0.0 和随机临时端口。


Pav*_*l P 5

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

#include <netinet/in.h>

struct in6_addr addr = IN6ADDR_ANY_INIT;
Run Code Online (Sandbox Code Playgroud)

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