116: rc = getnameinfo(addr, addrLen, NULL, 0,
117: serviceName, sizeof(serviceName), flags);
118: } else {
119: rc = getnameinfo(addr, addrLen, hostName, sizeof(hostName),
120: serviceName, sizeof(serviceName), flags);
121: }
122:
123: if (rc) {
124: fprintf(stderr, "сбой обратного поиска: %s\n",
125: gai_strerror(rc));
126: return 1;
127: }
128:
129: if (hostAddress)
130: printf("имя хоста: %s\n", hostName);
131: if (serviceAddress)
132: printf("имя службы: %s\n", serviceName);
133:
134: return 0;
135: }
17.5.7. Ожидание TCP-соединений
Ожидание соединений TCP происходит почти идентично ожиданию соединений домена Unix. Единственные различия заключаются в семействах протоколов и адресов. Ниже показан вариант примера сервера домена Unix, который работает через сокеты TCP.
1: /* tserver.с */
2:
3: /* Ожидает соединение на порте 4321. Как только соединение установлено,
4: из сокета в stdout копируются данные до тех пор, пока вторая
5: сторона не закроет соединение. Затем ожидает следующее соединение
6: с сокетом. */
7:
8: #include
9: #include
10: #include
11: #include
12: #include
13: #include
14: #include
15:
16: #include "sockutil.h" /* некоторые служебные функции */
17:
18: int main(void) {
19: int sock, conn, i, rc;
20: struct sockaddr address;
21: size_t addrLength = sizeof(address);
22: struct addrinfo hints, * addr;
23:
24: memset(&hints, 0, sizeof(hints));
25:
26: hints.ai_socktype = SOCK_STREAM;
27: hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
28: if ((rc = getaddrinfo(NULL, "4321", &hints, &addr))) {
29: fprintf(stderr, "сбой поиска имени хоста: %s\n",
30: gai_strerror(rc));
31: return 1;
32: }
33:
34: if ((sock = socket(addr->ai_family, addr->ai_socktype,
35: addr->ai_protocol)) < 0)
36: die("socket");
37:
38: /* Позволяет ядру повторно использовать адрес сокета. Это разрешает
39: нам запускать программу два раза подряд, не ожидая пока истечет
40: время для кортежа (ip-адрес, порт). */
41: i = 1;
42: setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
43:
44: if (bind(sock, addr->ai_addr, addr->ai_addrlen))
45: die("bind");
46:
47: freeaddrinfo(addr);
48:
49: if (listen(sock, 5))
50: die("listen");
51:
52: while ((conn = accept(sock, (struct sockaddr *) &address,
53: &addrLength)) >=0) {
54: printf("----получение данных\n");
55: copyData(conn, 1);
56: printf("----готово\n");
57: close(conn);
58: }
59:
60: if (conn < 0)
61: die("accept");
62:
63: close(sock);
64: return 0;
65: }
Обратите внимание на то, что IP-адрес, привязанный к сокету, указывает номер порта 4321, но не IP-адрес. Это предоставляет ядру возможность при необходимости воспользоваться локальным IP-адресом.
Код в строках 41–42 требует дополнительного объяснения.
41: i = 1;