2013-04-14 2 views
1

Использование winsock Я хочу, чтобы мое серверное приложение принимало соединения только из определенной (скажем, 192.168.0.0/24) подсети.Принимать соединения только из определенной подсети

Я имею в виду два варианта: адрес

  • Check клиента каждый раз, когда я 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; 
        } 
    
        ... 
    } 
    
  • Узнайте локальный адрес для соответствующей сети и использовать его в качестве аргумента в namebind

    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)); 
    

Какие еще варианты у меня есть?

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-адресам клиентов ранее и можете выбрать, принимать или отклонять отдельные клиенты, прежде чем они будут помещены в очередь для подключения.

Смежные вопросы