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