加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – 关于INADDR_ANY的问题

发布时间:2020-12-14 01:27:27 所属栏目:Linux 来源:网络整理
导读:The constant INADDR_ANY is the so-called IPv4 wildcard address. The wildcard IP address is useful for applications that bind Internet domain sockets on multihomed hosts. If an application on a multihomed host binds a socket to just one of

The constant INADDR_ANY is the so-called IPv4 wildcard address. The
wildcard IP address is useful for applications that bind Internet
domain sockets on multihomed hosts. If an application on a multihomed
host binds a socket to just one of its host’s IP addresses,then that
socket can receive only UDP datagrams or TCP connection requests sent
to that IP address. However,we normally want an application on a
multihomed host to be able to receive datagrams or connection requests
that specify any of the host’s IP addresses,and binding the socket to
the wildcard IP address makes this possible.

struct sockaddr_in server_address;
int server_sockfd = socket(AF_INET,SOCK_STREAM,0);
memset(&server_address,sizeof(struct sockaddr_in));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY); // here is my quesion
server_address.sin_port = htons(9734);

bind(server_sockfd,(struct sockaddr*)&server_address,sizeof(server_address));

问题>

如果我们将套接字绑定到特定的IP地址,则套接字只能接收发送到该IP地址的UPD / TCP请求.

正如我在上面的代码中所示,现在套接字server_sockfd与INADDR_ANY绑定.
我只是感到困惑,如果套接字可以在互联网上接收任何请求,它如何仍然可以正常工作b / c.如果套接字响应每个人,互联网上有大量的UDP / TCP请求,
,它怎么还能运作?

//更新客户端代码//

int
main(int argc,char *argv[])
{
    struct sockaddr_in6 svaddr;
    int sfd,j;
    size_t msgLen;
    ssize_t numBytes;
    char resp[BUF_SIZE];

    if (argc < 3 || strcmp(argv[1],"--help") == 0)
        usageErr("%s host-address msg...n",argv[0]);

    /* Create a datagram socket; send to an address in the IPv6 somain */

    sfd = socket(AF_INET6,SOCK_DGRAM,0);      /* Create client socket */
    if (sfd == -1)
        errExit("socket");

    memset(&svaddr,sizeof(struct sockaddr_in6));
    svaddr.sin6_family = AF_INET6;
    svaddr.sin6_port = htons(PORT_NUM);
    if (inet_pton(AF_INET6,argv[1],&svaddr.sin6_addr) <= 0)
        fatal("inet_pton failed for address '%s'",argv[1]);

    /* Send messages to server; echo responses on stdout */

    for (j = 2; j < argc; j++) {
        msgLen = strlen(argv[j]);
        if (sendto(sfd,argv[j],msgLen,(struct sockaddr *) &svaddr,sizeof(struct sockaddr_in6)) != msgLen)
            fatal("sendto");

        numBytes = recvfrom(sfd,resp,BUF_SIZE,NULL,NULL);
        if (numBytes == -1)
            errExit("recvfrom");

        printf("Response %d: %.*sn",j - 1,(int) numBytes,resp);
    }

    exit(EXIT_SUCCESS);
}

//为服务器端代码更新

int
main(int argc,char *argv[])
{
    struct sockaddr_in6 svaddr,claddr;
    int sfd,j;
    ssize_t numBytes;
    socklen_t len;
    char buf[BUF_SIZE];
    char claddrStr[INET6_ADDRSTRLEN];

    /* Create a datagram socket bound to an address in the IPv6 somain */

    sfd = socket(AF_INET6,0);
    if (sfd == -1)
        errExit("socket");

    memset(&svaddr,sizeof(struct sockaddr_in6));
    svaddr.sin6_family = AF_INET6;
    svaddr.sin6_addr = in6addr_any;                     /* Wildcard address */
    svaddr.sin6_port = htons(PORT_NUM);

    if (bind(sfd,sizeof(struct sockaddr_in6)) == -1)
        errExit("bind");

    /* Receive messages,convert to uppercase,and return to client */

    for (;;) {
        len = sizeof(struct sockaddr_in6);
        numBytes = recvfrom(sfd,buf,(struct sockaddr *) &claddr,&len);
        if (numBytes == -1)
            errExit("recvfrom");

        /* Display address of client that sent the message */

        if (inet_ntop(AF_INET6,&claddr.sin6_addr,claddrStr,INET6_ADDRSTRLEN) == NULL)
            printf("Couldn't convert client address to stringn");
        else
            printf("Server received %ld bytes from (%s,%u)n",(long) numBytes,ntohs(claddr.sin6_port));

        for (j = 0; j < numBytes; j++)
            buf[j] = toupper((unsigned char) buf[j]);

        if (sendto(sfd,numBytes,len) !=
                numBytes)
            fatal("sendto");
    }
}

//更新了如何运行此服务器/客户端程序.

$./server_program &
[1] 31047
$./client_program ::1 ciao // Send to server on local host
Server received 4 bytes from (::1,32770)
Response 1: CIAO

解决方法

它不会获得对互联网上每个IP地址的请求(a),它会收到它所服务的每个IP地址的请求.例如,它可能有多个NIC,每个NIC都有一个单独的IP地址,或者它可能有一个能够管理多个IP地址的NIC(它甚至可能有多个NIC,每个NIC都能够处理多个IP地址).

要看的关键片段是:

… we normally want an application on a multi-homed host to be able to receive datagrams or connection requests that specify any of the host’s IP addresses (my italics).

换句话说,您可能有一个多宿主设置,其中您的计算机服务10.0.0.15和10.0.0.16.使用INADDR_ANY将允许您为这两个地址获取流量,而不会获取10.0.0.17的请求,这可能是工作台另一端(或地球的另一端)的机器.

下表中,顶行是请求目的地,左列是您正在侦听的地址,显示您是否会收到请求(Y)或不(N):

Request to>  10.0.0.15  10.0.0.16  10.0.0.17
Bind to:    *-------------------------------
10.0.0.15   |    Y          N          N
10.0.0.16   |    N          Y          N
INADDR_ANY  |    Y          Y          N

(a)它甚至没有看到网上的绝大多数请求.绝大多数甚至没有到最近的路由器(或者甚至是你的ISP).即使那些确实能够到达最近的路由器,您的特定机器也可能看不到它们是否指定本地段上的另一台机器(尽管有混杂模式).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读