INADDR_ANY的確切含義

   INADDR_ANY就是inet_addr("0.0.0.0")服務器

        首先,須要明確的是當服務器的監聽地址是INADDR_ANY時設置的是服務器的IP地址。網絡

   其次,當服務器的監聽地址是INADDR_ANY時含義是讓服務器端計算機上的全部網卡的IP地址均可以做爲服務器IP地址,也即監聽外部客戶端程序發送到服務器端全部網卡的網絡請求。socket

    好比,個人網絡爲:192.168.1.102. 因而就有下面的程序:函數

        服務端:spa

#include <stdio.h>
#include <winsock2.h> // winsock接口
#pragma comment(lib, "ws2_32.lib") // winsock實現

int main()
{
    WORD wVersionRequested;  // 雙字節,winsock庫的版本
    WSADATA wsaData;         // winsock庫版本的相關信息
    
    wVersionRequested = MAKEWORD(1, 1); // 0x0101 即:257
    

    // 加載winsock庫並肯定winsock版本,系統會把數據填入wsaData中
    WSAStartup( wVersionRequested, &wsaData );
    

    // AF_INET 表示採用TCP/IP協議族
    // SOCK_STREAM 表示採用TCP協議
    // 0是一般的默認狀況
    unsigned int sockSrv = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN addrSrv;

    addrSrv.sin_family = AF_INET; // TCP/IP協議族
    addrSrv.sin_addr.S_un.S_addr = INADDR_ANY; //inet_addr("0.0.0.0"); 
    addrSrv.sin_port = htons(8888); // socket對應的端口

    // 將socket綁定到某個IP和端口(IP標識主機,端口標識通訊進程)
    bind(sockSrv,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

    // 將socket設置爲監聽模式,5表示等待鏈接隊列的最大長度
    listen(sockSrv, 5);

    SOCKADDR_IN addrClient;
    int len = sizeof(SOCKADDR);

    while(1)
    {
        // sockSrv爲監聽狀態下的socket
        // &addrClient是緩衝區地址,保存了客戶端的IP和端口等信息
        // len是包含地址信息的長度
        // 若是客戶端沒有啓動,那麼程序一直停留在該函數處
        unsigned int sockConn = accept(sockSrv,(SOCKADDR*)&addrClient, &len);
        
        char sendBuf[100] = {0};
        sprintf(sendBuf,"%s", inet_ntoa(addrClient.sin_addr)); // 將客戶端的IP地址保存下來
        send(sockConn, sendBuf, strlen(sendBuf) + 1, 0); // 發送數據到客戶端,最後一個參數通常設置爲0

        char recvBuf[100] = {0};
        recv(sockConn, recvBuf, 100, 0); // 接收客戶端數據,最後一個參數通常設置爲0
        printf("%s\n", recvBuf);
        closesocket(sockConn);
    }
        
    closesocket(sockSrv);
    WSACleanup();
    
    return 0;
}

客戶端:code

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")

int main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD(1, 1);
    
    WSAStartup( wVersionRequested, &wsaData );

    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.102");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(8888);
    int ret = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

    char recvBuf[100] = {0};
    recv(sockClient, recvBuf, 100, 0);
    printf("%s\n", recvBuf);
    send(sockClient, "hello world", strlen("hello world") + 1, 0);

    closesocket(sockClient);
    WSACleanup();

    return 0;
}

固然客戶端也能夠用回測地址(設服務端與客戶端在同一臺機子上):blog

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")

int main()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD(1, 1);
    
    WSAStartup( wVersionRequested, &wsaData );

    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);

    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(8888);
    int ret = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

    char recvBuf[100] = {0};
    recv(sockClient, recvBuf, 100, 0);
    printf("%s\n", recvBuf);
    send(sockClient, "hello world", strlen("hello world") + 1, 0);

    closesocket(sockClient);
    WSACleanup();

    return 0;
}

  固然啦,若是服務端用192.168.1.102做爲監聽IP,客戶端用192.168.1.102去connect,  那也是能夠的。接口

 

"將sin_addr設置爲INADDR_ANY"的含義是什麼?

問:隊列

  不少書上都說「將sin_addr設置爲INADDR_ANY,則表示全部的IP地址,也即全部的計算機」,這樣的解說讓人費解。進程

答:

  INADDR_ANY轉換過來就是0.0.0.0,泛指本機的意思,也就是表示本機的全部IP,由於有些機子不止一塊網卡,多網卡的狀況下,這個就表示全部網卡ip地址的意思。

  當服務器的監聽地址是INADDR_ANY時,意思不是監聽全部的客戶端IP。而是服務器端的IP地址能夠隨意配置,這樣使得該服務器端程序能夠運行在任意計算機上,可以使任意計算機做爲服務器,便於程序移植。將INADDR_ANY換成127.0.0.1也能夠達到一樣的目的。這樣,看成爲服務器的計算機的IP有變更或者網卡數量有增減,服務器端程序都可以正常監聽來自客戶端的請求。我是這麼理解的。

  好比一臺電腦有3塊網卡,分別鏈接三個網絡,那麼這臺電腦就有3個ip地址了,若是某個應用程序須要監聽某個端口,那他要監聽哪一個網卡地址的端口呢?若是綁定某個具體的ip地址,你只能監聽你所設置的ip地址所在的網卡的端口,其它兩塊網卡沒法監聽端口,若是我須要三個網卡都監聽,那就須要綁定3個ip,也就等於須要管理3個套接字進行數據交換,這樣豈不是很繁瑣?因此出現INADDR_ANY,你只需綁定INADDR_ANY,管理一個套接字就行,無論數據是從哪一個網卡過來的,只要是綁定的端口號過來的數據,均可以接收到。

相關文章
相關標籤/搜索