Как отличить два разных UDP-клиента на одном и том же IP-адресе? - PullRequest
7 голосов
/ 11 апреля 2010

Я пишу сервер UDP, который для меня первый; Я только немного пообщался по TCP. И у меня возникли проблемы с выяснением, как именно определить, кто какой пользователь, поскольку UDP работает только с пакетами, а не с соединениями, и поэтому я не могу точно сказать, с кем я общаюсь.

Вот псевдокод моего текущего цикла сервера:

DatagramPacket p;
socket.receive(p); // now p contains the user's IP and port, and the data
int key = getKey(p);
if(key == 0) { // connection request
    key = makeKey(p);
    clients.add(key, p.ip);
    send(p.ip, p.port, key); // give the user his key
} else { // user has a key
    // verify key belongs to that IP address
    // lookup the user's session data based on the key
    // react to the packet in the context of the session
}

При разработке этого я учел следующие моменты:

  • Из-за наличия маршрутизаторов на одном и том же IP-адресе могут существовать несколько пользователей, поэтому у пользователей должен быть отдельный идентификационный ключ.
  • Пакеты могут быть подделаны, поэтому ключ должен быть проверен по его первоначальному IP-адресу и проигнорирован, если другой IP-адрес пытается использовать ключ.
  • Исходящий порт на стороне клиента может изменяться среди пакетов.

Это третье предположение верно, или я могу просто предположить, что один пользователь = одна комбинация IP + порт? Это обычно делается, или я должен продолжать создавать специальный ключ, как я делаю в настоящее время?

Я не совсем понимаю, как TCP согласовывает соединение, поэтому, если вы считаете, что я должен смоделировать его с TCP, пожалуйста, свяжите меня с хорошим учебником или с чем-нибудь из TCP SYN / SYNACK / ACK mess.

Также обратите внимание, у меня есть условие для повторной отправки ключа, если IP отправляет 0 и этот IP уже имеет ожидающий ключ; Я опустил его, чтобы сделать фрагмент простым. Я понимаю, что UDP не гарантирован, и я планирую добавить надежность к основному коду обработки пакетов позже.

Ответы [ 3 ]

7 голосов
/ 11 апреля 2010

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

2 голосов
/ 11 апреля 2010
* The outbound port on the client side might change among packets.

Это третье предположение верно

Нет, если клиент продолжает использовать один и тот же исходящий сокет. Отправка первой дейтаграммы вызовет локальное связывание, поэтому с этого момента сокет будет находиться на фиксированном локальном порту.

2 голосов
/ 11 апреля 2010

Ваши вопросы - это лишь верхушка списка вопросов, которые нужно знать при использовании UDP. Вы должны ожидать, что маршрутизаторы NAT не смогут обеспечить какую-либо значимую переадресацию протокола UDP, который вы разрабатываете. TCP работает, потому что маршрутизаторы понимают конечный автомат TCP и сохраняют состояние соединения каждого сеанса, чтобы знать, как его переслать. Они будут не знать , как работает ваш собственный протокол UDP. Устройства NAT включают специальные обработчики протоколов для хорошо известных приложений UDP.

Если отправитель связан с исходным портом и / или интерфейсом, исходные порты отправителя остаются неизменными до тех пор, пока они не будут связаны.

С помощью UDP вы можете привязать обоих пиров к известному исходному порту для (dst) входящих и (или src) исходящих сообщений. Для клиент-серверных приложений вы обычно хотите, чтобы клиент связывался с динамическим портом источника, чтобы несколько клиентов могли сосуществовать в одной клиентской системе. Затем сервер может ответить клиенту, используя динамический порт источника, предоставленный через порт src, из запроса, используемого в качестве порта назначения в ответе. Использование известного порта для одноранговых узлов позволяет настроить переадресацию UDP в устройствах NAT.

бывший клиент / сервер с сервером на известном порту 3000

клиент связывается со случайным портом (1234), но знает, что сервер прослушивает порт 3000. клиент (src 1234) -> сервер (dst 3000) сервер (dst 1234) -> клиент (src 3000) ...

Если компьютер имеет несколько интерфейсов, вам следует ожидать либо явного связывания слушателя или отправителя с конкретным IP-адресом, либо возможности обработки запросов и ответов от однорангового узла, отправляемого и получаемого с случайного IP на основе капризов таблицы маршрутизации компьютеров. Если вы решите связать запросы с конкретным интерфейсом, то вам необходимо знать таблицу маршрутизации, если сообщения от мультидоменной системы должны проходить через другой локальный интерфейс для доставки. Например, если вы привязали сокет UDP к 127.0.0.1, вы, очевидно, не сможете использовать его для отправки на любые маршрутизируемые IP-адреса в Интернете.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...