Вход/Регистрация
Основы программирования в Linux
вернуться

Мэтью Нейл

Шрифт:

Дейтаграммы

В этой главе мы сосредоточились на программировании приложений, поддерживающих связь со своими клиентами с помощью TCP-соединений на базе сокетов. Существуют ситуации, в которых затраты на установку и поддержку соединения с помощью сокетов излишни.

Хорошим примером может служить сервис

daytime
, использованный ранее в программе getdate.c. Вы создаете сокет, выполняете соединение, читаете единственный ответ и разрываете соединение. Столько операций для простого получения даты!

Сервис

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

Сервисы, предоставляемые по UDP-протоколу, применяются в тех случаях, когда клиенту нужно создать короткий запрос к серверу, и он ожидает единственный короткий ответ. Если стоимость времени процессора достаточно низкая, сервер способен обеспечить такой сервис, обрабатывая запросы клиентов по одному и разрешая операционной системе хранить очередь входящих запросов. Такой подход упрощает программирование сервера.

Поскольку UDP — не дающий гарантий сервис, вы можете столкнуться с потерей вашей дейтаграммы или ответа сервера. Если данные важны для вас, возможно, придется тщательно программировать ваших UDP-клиентов, проверяя ошибки и при необходимости повторяя попытки. На практике в локальных сетях UDP-дейтаграммы очень надежны.

Для доступа к сервису, обеспечиваемому UDP-протоколом, вам следует применять системные вызовы

socket
и
close
, но вместо использования вызовов
read
и
write
для сокета вы применяете два системных вызова, характерных для дейтаграмм:
sendto
и
recvfrom
.

Далее приведена модифицированная версия программы getdate.c, которая получает дату с помощью сервиса UDP-дейтаграмм. Изменения по сравнению с предыдущей версией выделены цветом.

/* Начните с обычных include и объявлений. */

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

int main(int argc, char *argv[]) {

 char *host;

 int sockfd;

 int len, result;

 struct sockaddr_in address;

 struct hostent *hostinfo;

 struct servent *servinfo;

 char buffer[128];

 if (argc == 1) host = "localhost";

 else host = argv[1];

 /* Ищет адрес хоста и сообщает об ошибке, если не находит. */

 hostinfo = gethostbyname(host);

 if (!hostinfo) {

fprintf(stderr, "no host: %s\n", host);

exit(1);

 }

 /* Проверяет наличие на компьютере сервиса daytime. */

 servinfo = getservbyname("daytime", "udp");

 if (!servinfo) {

fprintf(stderr, "no daytime service\n");

exit(1);

 }

 printf("daytime port is %d\n", ntohs(servinfo->s_port));

 /* Создает UDP-сокет. */

 sockfd = socket(AF_INEТ, SOCK_DGRAM, 0); 

 /* Формирует адрес для использования в вызовах sendto/recvfrom... */

 address.sin_family = AF_INET;

 address.sin_port = servinfo->s_port;

 address.sin_addr = *(struct in_addr*)*hostinfo->h_addr_list;

 len = sizeof(address);

 result = sendto(sockfd, buffer, 1, 0, (struct sockaddr *)&address, len);

 result = recvfrom(sockfd, buffer, sizeof(buffer), 0,

(struct sockaddr *)&address, &len);

 buffer [result] = '\0';

 printf("read %d bytes: %s", result, buffer);

 close(sockfd);

  • Читать дальше
  • 1
  • ...
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: