Я могу понять концепцию TCP vs UDP, но все же я не понимаю, почему есть два способа отправки UDP-пакетов, и с этим я до сих пор не понимаю, нужно ли это обязательно связывать() и принимать ()...
Какая цель использования sendto/recvfrom вместо connect/send/recv с сокетами UDP?
Ответ 1
-
accept()
для TCP. Это не имеет никакого отношения к UDP. -
connect()
в UDP ничего не делает с другим концом, он просто заставляет локальный API знать, от кого вы отправляете и получаете. -
Если вы еще этого не знаете или не хотите или хотите отправить нескольким адресатам с одним и тем же сокетом, вы не используете
connect()
, вместо этого вы используетеsendto()
. Аналогично для приема.Рассмотрим, например, UDP-сервер. Он вызывет
recvfrom(),
, чтобы получить информацию об исходном адресе, обработать запрос, создать ответ и отправить его на этот адрес черезsendto().
Noconnect()
, где угодно, 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, конечно, не выполняет никакого рукопожатия для подключения.)
Надеюсь, что это поможет.