Какая цель использования 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, конечно, не выполняет никакого рукопожатия для подключения.)
Надеюсь, что это поможет.