results for host localhost:
Name: localhost
Aliases: 127.0.0.1
Теперь вы можете изменить свою программу-клиента для соединения с любым именованным узлом сети. Вместо подключения к серверу из вашего примера, вы соединитесь со стандартным сервисом и сможете извлечь номер порта.
Большинство систем UNIX и некоторые ОС Linux делают доступными свои системные время и дату в виде стандартного сервиса с именем daytime
. Клиенты могут подключаться к этому сервису для выяснения мнения сервера о текущих времени и дате. В упражнении 15:6 приведена программа-клиент getdate.c, именно это и делающая.
1. Начните с обычных директив #include
и объявлений:
#include
#include
#include
#include
#include
#include
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];
2. Найдите адрес узла и сообщите об ошибке, если адрес не найден:
hostinfo = gethostbyname(host);
if (!host info) {
fprintf(stderr, "no host: %s\n", host);
exit(1);
}
3. Убедитесь, что на компьютере есть сервис daytime
:
servinfo = getservbyname("daytime", "tcp");
if (!servinfo) {
fprintf(stderr, "no daytime service\n");
exit(1);
}
printf("daytime port is %d\n", ntohs(servinfo->s_port));
4. Создайте сокет:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
5. Сформируйте адрес для соединения:
address.sin_family = AF_INET;
address.sin_port = servinfo->s_port;
address.sin_addr = *(struct in_addr *)*hostinfo->h_addr_list;
len = sizeof(address);
6. Затем подключитесь и получите информацию:
result = connect(sockfd, (struct sockaddr *)&address, len);
if (result == -1) {
perror("oops: getdate");
exit(1);
}
result = read(sockfd, buffer, sizeof(buffer));
buffer[result] = '\0';
printf("read %d bytes: %s", result, buffer);
close(sockfd);
exit(0);
}
Вы можете применять программу getdate
для получения времени суток с любого известного узла сети.
$ ./getdate localhost
daytime port is 13
read 26 bytes: 24 JUN 2007 06:03:03 BST
$
Если вы получаете сообщение об ошибке, такое как
oops: getdate: Connection refused
или
oops: getdate: No such file or directory
причина может быть в том, что на компьютере, к которому вы подключаетесь, не включен сервис daytime
. Такое поведение стало стандартным для большинства современных систем Linux. В следующем разделе вы увидите, как включать этот и другие сервисы.
Как это работает
При выполнении данной программы можно задать узел, к которому следует подключиться. Номер порта сервиса daytime
определяется функцией сетевой базы данных getservbyname
, которая возвращает сведения о сетевых сервисах таким же способом, как и при получении информации об узле сети. Программа getdate
пытается соединиться с адресом, который указан первым в списке дополнительных адресов заданного узла. Если соединение успешно, программа считывает сведения, возвращаемые сервисом daytime, символьную строку, содержащую системные дату и время.
Интернет-демон (xinetd/inetd)
Системы UNIX, предоставляющие ряд сетевых сервисов, зачастую делают это с помощью суперсервера. Эта программа (интернет-демон xinetd или inetd) ожидает одновременно запросы на соединения с множеством адресов портов. Когда клиент подключается к сервису, программа-демон запускает соответствующий сервер. При таком подходе серверам не нужно работать постоянно, они могут запускаться по требованию.