UNIX: разработка сетевых приложений | страница 7



Чтобы упростить написанный нами код, мы определяем наши собственные функции-обертки (wrapper functions) для большинства вызываемых системных функций. Функции-обертки в большинстве случаев служат для проверки кода возврата. В случае ошибки функция-обертка печатает соответствующее сообщение и завершает работу программы.

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

В разговорах о Unix широко используется термин «X», обозначающий стандарт, принятый большинством производителей. Мы опишем историю стандарта POSIX и то, каким образом он определяет интерфейсы программирования приложений (Application Programming Interfaces, API), рассматриваемые в этой книге, наряду с другими конкурирующими стандартами.

1.2. Простой клиент времени и даты

Рассмотрим конкретный пример, на котором мы введем многие понятия и термины, используемые в этой книге. В листинге 1.1[1] представлена реализация TCP-клиента времени и даты. Этот клиент устанавливает TCP-соединение с сервером, а сервер просто посылает клиенту время и дату в текстовом формате.

Листинг 1.1. Клиент TCP для определения времени и даты

>//intro/daytimetcpcli.с

> 1 #include "unp.h"


> 2 int

> 3 main(int argc, char **argv)

> 4 {

> 5  int sockfd, n;

> 6  char recvline[MAXLINE + 1];

> 7  struct sockaddr_in servaddr;


> 8  if (argc != 2)

> 9   err_quit("usage: a.out ");


>10  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

>11   err_sys("socket error");


>12  bzero(&servaddr, sizeof(servaddr));

>13  servaddr.sin_family = AF_INET;

>14  servaddr.sin_port = htons(13); /* сервер времени и даты */

>15  if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)

>16   err_quit("inet_pton error for %s", argv[1]);


>17  if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) < 0)

>18   err_sys("connect error");


>19  while ((n = read(sockfd, recvline, MAXLINE)) > 0) {

>20   recvline[n] = 0; /* завершающий нуль */

>21   if (fputs(recvline, stdout) == EOF)

>22    err_sys("fputs error");

>23  }

>24  if (n < 0)

>25  err_sys("read error");


>26  exit(0);

>27 }

ПРИМЕЧАНИЕ

Это формат, который мы используем для всего исходного кода в тексте. Каждая непустая строка пронумерована. Абзац, описывающий некоторую часть кода, начинается с двух номеров — начального и конечного номеров тех строк, о которых идет речь в данном абзаце. Как правило, абзацу предшествует короткий заголовок, в котором кратко резюмируется содержание описываемого кода.