Skip to content

Latest commit

 

History

History
55 lines (39 loc) · 3.04 KB

File metadata and controls

55 lines (39 loc) · 3.04 KB

Сокеты UDP-датаграмм

Реализуем несколько программ: talker.c и listener.c

  • listener (сервер) запускается и ожидает входящих пакетов на порте 4950.

  • talker (клиент) отправляет на этот порт сообщение из командой строки.

Так как UDP-сокеты являются connectionless и просто отправляют пакеты, несмотря на доступность получателя, мы реализуем и клиент и сервер с использованием IPv6.

Это позволит избежать ситуации, когда клиент запущен на одной версии протокола, а сервер на другой, в этом случае пакет просто не будет получен.

В случае с TCP, когда клиент и сервер на разных протоколах (IPv6/IPv4), в системных вызовах (например, accept()) будет соответствующая ошибка. Хороший пример обработки ошибок, со стороны TCP.

В listener.c обратите внимание, что в отличии от TCP-сервера, мы используем SOCK_DGRAM. Также, UDP-серверу не требуется вызывать listen() и accept(), он просто вызывает recvfrom() и ждет пакетов от клиента:

int num_bytes = recvfrom(sockfd, buf, MAXBUFLEN - 1, 0, (struct sockaddr*)&their_addr, &addr_len);

Реализация talker.c просто отправляет байты по заданному адресу. UDP-клиент не волнует, получил ли пакеты получатель или нет, он их просто отпрвляет. Помните, что UDP не гарантирует доставку пакетов.

В одном терминале запустим listener:

$ ./listener
listener: waiting to recvfrom...

В другом talker, передав ему адрес и сообщение:

$ ./talker localhost heyMan
talker: sent 6 bytes to localhost

В listener сообщение получено:

# ...
listener: got packet from ::1
listener: packet is 6 bytes long
listener: packet contains "heyMan"

talker можно запускать и без включенного сервера, пакеты он отправит, но они просто исчезнут, ибо некому их получать:

$ ./talker localhost heyMan
talker: sent 6 bytes to localhost

$ ./talker localhost heyMan
talker: sent 6 bytes to localhost

$ ./talker localhost heyMan
talker: sent 6 bytes to localhost