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

#sockets #networking #network-programming #udp

#розетки #сеть #сетевое программирование #udp

Вопрос:

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

Ответ №1:

  1. accept() предназначен для TCP. Это не имеет ничего общего с UDP.

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

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

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

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

Комментарии:

1. что насчет listen() ? и что касается метода bind (), означает ли это, что я получаю все, что поступает на этот порт?

2. @gokoon 1. listen() предназначен для TCP. Это не имеет ничего общего с UDP. 2. Что именно означает «как насчет bind ()» в качестве вопроса? 3. Да, вы получаете все, что адресовано этому UDP-порту, если вы не подключены.

3. @EJP Это linux.die.net/man/7/udp говорится, что при вызове connect() UDP использует чтение / запись! Итак, чтение / запись или отправка / recv?

4. @entropy Нет, это не так. В нем говорится: «Когда в сокете вызывается connect(2), устанавливается адрес назначения по умолчанию, и дейтаграммы теперь можно отправлять с помощью send(2) или write(2)». Аналогично в этом случае вы можете использовать либо read(), либо recv() .

5. @EJP Если я выполняю функцию bind() перед первыми вызовами sendto(), переопределяет ли она автоматическую привязку (), выполняемую первыми вызовами send() / sendto () / recv() / revfrom() ?

Ответ №2:

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

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

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

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

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