Какая цель использования sendto/recvfrom вместо connect/send/recv с сокетами UDP?

Я могу понять концепцию TCP vs UDP, но все же я не понимаю, почему есть два способа отправки UDP-пакетов, и с этим я до сих пор не понимаю, нужно ли это обязательно связывать() и принимать ()...

Ответ 1

  • accept() для TCP. Это не имеет никакого отношения к UDP.

  • connect() в UDP ничего не делает с другим концом, он просто заставляет локальный API знать, от кого вы отправляете и получаете.

  • Если вы еще этого не знаете или не хотите или хотите отправить нескольким адресатам с одним и тем же сокетом, вы не используете connect(), вместо этого вы используете sendto(). Аналогично для приема.

    Рассмотрим, например, UDP-сервер. Он вызывет recvfrom(),, чтобы получить информацию об исходном адресе, обработать запрос, создать ответ и отправить его на этот адрес через sendto(). No connect(), где угодно, ergo невозможно использовать либо send(), либо recv().

  • Необходимо только bind() сервер, потому что клиентам нужен номер фиксированного порта для отправки. Клиенту не требуется bind() вообще: автоматическая привязка() будет выполняться в первом send()/sendto()/recv()/recvfrom() с использованием назначенного системой номера локального порта.

Ответ 2

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

  • TCP: вам нужно подключиться первым до отправки/получения данных на/с удаленного хоста.
  • UDP: подключение не требуется. Вы можете отправлять/получать данные на/с любого хоста.

Обычно вы используете sendto() в сокете UDP для указания адресата. Аналогично, вы обычно используете recvfrom(), чтобы знать, откуда были получены данные UDP.

Однако вы можете использовать connect() для сокета UDP в качестве опции. В этом случае вы можете использовать send()/recv() в сокете UDP для отправки данных по адресу, указанному с помощью connect(), и получать данные только с адреса. (Разъем connect() на UDP-соке просто устанавливает адрес одноранговой сети по умолчанию, и вы можете вызывать connect() в соке UDP столько раз, сколько хотите, а connect() на соке UDP, конечно, не выполняет никакого рукопожатия для подключения.)

Надеюсь, что это поможет.