11.3.1. Отображение текущего времени
11.3.1. Отображение текущего времени
Модуль time.so (исходный текст приведен в листинге 11.6) генерирует простую страницу, где отображается текущее время на сервере. В функции module_generate() вызывается функция gettimeofday(), возвращающая значение текущего времени (см. раздел 8.7, "Функция gettimeofday(): системные часы"), после чего функции localtime() и strftime() преобразуют это значение в текстовый формат. Полученная строка встраивается в шаблон HTML-страницы page_template.
Листинг 11.6. (time.c) серверный модуль, отображающий текущее время
#include <assert.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include "server.h"
/* шаблон HTML-страницы, генерируемой данным модулем. */
static char* page_template =
"<html> "
" <head> "
" <meta http-equiv="refresh" content="5"> "
" </head> "
" <body> "
" <p>The current time is %s </p> "
" </body> "
"</html> ";
void module_generate(int fd) {
struct timeval tv;
struct tm* ptm;
char time_string[40];
FILE* fp;
/* Определение времени суток и заполнение структуры типа tm. */
gettimeofday(&tv, NULL);
ptm = localtime(&tv.tv_sec);
/* Получение строкового представления времени с точностью
до секунды. */
strftime(time_string, sizeof(time_string), "%H:%M:%S", ptm);
/* Создание файлового потока, соответствующего дескриптору
клиентского сокета. */
fp = fdopen(fd, "w");
assert(fp != NULL);
/* Запись HTML-страницы. */
fprintf(fp, page_template, time_string);
/* Очистка буфера потока */
fflush(fp);
}
Для удобства в этом модуле используются стандартные библиотечные функции ввода-вывода. Функция fdopen() возвращает указатель потока (FILE*), соответствующий дескриптору клиентского сокета (подробнее об этом рассказывается в приложении Б, "Низкоуровневый ввод-вывод"). Для отправки страницы клиенту вызывается обычная функция fprintf(), а функция fflush() предотвращает потерю данных в случае закрытия сокета.
HTML-страница, возвращаемая модулем time.so, содержит в заголовке тэг <meta>, который служит клиенту указанием перезагружать страницу каждые 5 секунд. Благодаря этому клиент всегда будет знать точное время.