了解INADDR_ANY以进行套接字编程

时间:2013-05-12 15:02:01

标签: c sockets

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

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

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

5 个答案:

答案 0 :(得分:97)

    bind()的{​​li>

    INADDR_ANY “生成随机IP”。它binds the socket to all available interfaces

  1. 对于服务器,您通常希望绑定到所有接口 - 而不仅仅是“localhost”。

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

  3. 碰巧,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
    ...
    
  4. 如果您还不熟悉它,我建议您查看Beej的套接字编程指南:

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

  5. 由于人们仍在阅读此内容,请另外注意:

      

    man (7) ip

         

    当进程想要接收新的传入数据包或连接时,   它应该使用bind(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() — Bind a name to a socket

         

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

答案 1 :(得分:57)

当您不需要将套接字绑定到特定IP时,将使用

INADDR_ANY。当您在调用bind()时使用此值作为地址时,套接字接受与计算机的所有IP的连接。

答案 2 :(得分:7)

绑定套接字 localhost ,在调用 bind 函数之前,应正确设置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);

答案 3 :(得分:0)

INADDR_ANY是一个常量,其值包含0。只有当您想要从不关心ip-add的所有活动端口进行连接时,才会使用此选项。 所以,如果你想连接任何特定的IP你应该提到像   my_sockaddress.sin_addr.s_addr = inet_addr(" 192.168.78.2")

答案 4 :(得分:0)

当你有一个服务器时,你创建一个套接字,然后将它绑定到一个 IP 和端口,这为套接字提供了一种基于唯一的套接字类型、地址族、IP 和端口进行识别的唯一方式。然后使用listen() 将套接字设置为服务器模式,然后执行accept(),它会等待一个连接,该连接将具有目标参数的入站数据包,这些数据包会在该套接字上排队。

当你有一个客户端时,你创建一个套接字,然后将套接字连接()到远程 IP 和端口,如果它还没有,它也会将 0.0.0.0 和一个随机未使用的临时端口绑定到套接字已经使用 bind(INADDR_ANY, 0) 绑定到 IP 和端口。 connect() 连接时返回,并使用 IP 和端口作为出站数据包中的源地址,其中 0.0.0.0 始终由操作系统替换为当前内部 IP,然后您使用 sendall 发送应用程序数据。< /p>

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

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