2012-03-02 17 views
0

Я в настоящее время программирую приложение UDP, которое позволяет клиентам входить в систему. После этого их конечная точка сохраняется в списке.UDP и рандомизация порта

private void socket_Callback(IAsyncResult result_) 
{ 
    EndPoint remote = new IPEndPoint(IPAddress.Any, 0); 
    socket.EndReceiveFrom(result_, ref remote); 

    if (!listOfEndPoints.Contains(remote)) 
    { 
     // registration process 

     // add it to list 
     listOfEndPoints.Add(remote) 
    } 
    else 
    { 
     // process packet 
    } 
} 

Однако иногда NAT клиента назначает каждому пакету другую внешнюю конечную точку. Если конечная точка исходного пакета регистрации составляет 12.34.56.78:1000, эта конечная точка добавляется в список. Если один и тот же клиент отправляет другой пакет, NAT назначит ему другой порт, поэтому его конечная точка будет 12.34.56.78:1001. Это приводит к тому, что сервер не регистрируется и пытается обработать пакет в качестве регистрационного. Излишне говорить, что это не сработает.

Способом устранения этого является отправка идентификатора (который, однако, может быть легко сфальсифицирован, если он не является сверхкритическим) для клиента. Тем не менее, клиент должен будет добавить его к каждому отправленному ему серверу. Так что было бы не очень эффективно делать это так.

Есть ли другой способ сказать, что пакет пришел от того же клиента, что и пакет регистрации?

ответ

3

Вы должны обязательно указать , а не использовать исходный IP-адрес и порт UDP-пакета для связывания его с логическим соединением. Вы должны указать идентификатор соединения в каждом пакете и обновить IP-адрес и порт, на которые вы отвечаете, если вы получаете новый IP-адрес и порт для того же логического соединения. Если соединение hi-jacking является проблемой, вам может потребоваться реализовать некоторую форму безопасности, такую ​​как безопасная контрольная сумма в дейтаграмме.

TCP обрабатывает пакеты с подключениями для вас. С UDP вы должны сами связывать дейтаграммы с логическими сеансами. Я не знаю, почему вы думаете, что «было бы не очень эффективно это делать».

Одним из компромиссов UDP является то, что если вам нужно что-либо, что обеспечивает TCP, вы должны сами его закодировать.

Кстати, я никогда не видел сдвиг портов таким образом. Вы уверены, что клиентский код не сломан, возможно, открывает новый сокет для каждой отправляемой датаграммы.

+0

Спасибо! Если это был ошибка в моем коде, почему я не должен использовать конечную точку пакета? Разве это не будет уникальным для каждого клиента? И как выглядит безопасная контрольная сумма? Я думал о отправке случайного числа клиенту, когда он зарегистрирован. Затем клиент будет добавлять md5 (контрольная сумма XOR пакета данных) в пакет. Затем сервер проверит правильность контрольной суммы. Это вы имели в виду? – haiyyu

+1

@haiyyu: Причина, по которой не использовать данные конечной точки, заключается в том, что IP-адрес другого конца может измениться. С TCP понимается, что сети необходимо связывать пакеты с сеансом, а устройства NAT - для сохранения IP-адресов. С UDP они этого не делают. И да, это то, что я имел в виду. Разумеется, лучшее решение зависит от ваших требований. –

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