Добавить в цитаты Настройки чтения

Страница 278 из 324

 exit(0);

}

Как видите, необходимы лишь незначительные изменения. Как и раньше, вы ищете сервис daytime с помощью вызова getservbyname, но задаете дейтаграммный сервис, запрашивая UDP-протокол. Дейтаграммный сокет создается с помощью вызова socket с параметром SOCK_DGRAM. Адрес назначения задается, как и раньше, но теперь вместо чтения из сокета вы должны послать дейтаграмму.

Поскольку вы не устанавливаете явное соединение с сервисами на базе UDP, у вас должен быть способ оповещения сервера о том, что вы хотите получить ответ. В данном случае вы посылаете дейтаграмму (в нашем примере вы отправляете один байт из буфера, в который вы хотите получить ответ) сервису и он посылает в ответ дату и время.

Системный вызов sendto отправляет дейтаграмму из буфера на сокет, используя адрес сокета и длину адреса. У этого вызова фактически следующий прототип:

<b>int sendto(int sockfd, void *buffer, size_t len, int flags,</b>

<b> struct sockaddr *to, socklen_t tolen);</b>

В случае обычного применения параметр flags можно оставлять нулевым.

Системный вызов recvfrom ожидает дейтаграмму в соединении сокета с заданным адресом и помещает ее в буфер. У этого вызова следующий прототип:

<b>int recvfrom(int sockfd, void *buffer, size_t len, int flags,</b>

<b> struct sockaddr *from, socklen_t *fromlen);</b>

И снова в случае обычного применения параметр flags можно оставлять нулевым.

Для упрощения примера мы пропустили обработку ошибок. Оба вызова, sendto и recvfrom, в случае возникновения ошибки вернут -1 и присвоят переменной errno соответствующее значение. Возможные ошибки перечислены в табл. 15.6.

Таблица 15.6