2013-04-14 49 views
1

使用winsock我希望我的服務器應用程序只接受來自某個特定子網(比如192.168.0.0/24)的連接。每次只接受來自特定子網的連接

  • 檢查客戶端的地址我accept連接:

    我想到的兩種選擇。

    while (true) { 
        SOCKET clientSocket = accept(serverSocket, 
               (SOCKADDR *)&clientAddress, 
               &addressLenght); 
        if (clientSocket == INVALID_SOCKET 
        || clientAddress.sin_addr.S_un.S_un_b.s_b1 != 192 
        || clientAddress.sin_addr.S_un.S_un_b.s_b2 != 168 
        || clientAddress.sin_addr.S_un.S_un_b.s_b3 != 0) { 
         closesocket(clientSocket); 
         continue; 
        } 
    
        ... 
    } 
    
  • 找出本地地址對應的網絡和bind

    SOCKADDR_IN serverAddress; 
    serverAddress.sin_family = AF_INET; 
    serverAddress.sin_port = htons(13666); 
    serverAddress.sin_addr.S_un.S_addr = inet_addr("192.168.0.1"); 
    
    result = bind(serverSocket, (SOCKADDR *)&serverAddress, 
           sizeof(serverAddress)); 
    

我有什麼其他選擇使用它作爲name說法?

P.S .:我被告知有更好的解決方案。但我無法弄清楚。

+0

我希望地址實際上是從一個配置文件中加載的,否則每次網絡需要重組並因此重新編號時,網絡管理員都會「愛」你! –

+0

@EmilioGaravaglia是的,當然。上面的代碼僅僅是一個例子。 – Igonato

+0

「有人告訴我有更好的解決方案」 - 但他們不會費心去解釋至少一點? –

回答

1

如果您只希望來自服務器所在的同一子網的連接(您的問題中不清楚是否如此),則可以使用setsockopt()將TTL設置爲1.該套接字的數據包(包括連接握手)不應該穿過路由器。

1

如果您只想在一個子網上監聽客戶端,則正確的解決方案是bind()對應於該子網的適配器的本地IP的單個監聽套接字。讓操作系統爲您做濾波。

如果您需要偵聽多個子網的客戶端,您可以bind()需要一個獨立的監聽套接字到每個子網本地IP,也可以bind()一個插座INADDR_ANY(0.0.0.0),然後在客戶端過濾的手動。

如果您手動過濾,則應使用WSAAccept()而不是accept(),以便您可以使用其回調函數CONDITIONPROC。不同之處在於,當使用accept()時,客戶端無條件地被操作系統接受到隊列中,並在您的代碼訪問它們之前通過accept()完全連接。如果使用WSAAccept()代替,則可以提前訪問客戶端遠程IP,並且可以選擇是否接受或拒絕各個客戶端,然後將它們放入要連接的隊列中。

相關問題