№ процесса или потока | Предварительное создание процессов без защиты accept (строка 2) | Предварительное создание процессов с защитой accept (строка 3) | Предварительное создание процессов, передача дескриптора (строка 5) | Предварительное порождение потоков, защита accept (строка 7) |
---|---|---|---|---|
0 | 333 | 347 | 1006 | 333 |
1 | 340 | 328 | 950 | 323 |
2 | 335 | 332 | 720 | 333 |
3 | 335 | 335 | 583 | 328 |
4 | 332 | 338 | 485 | 329 |
5 | 331 | 340 | 457 | 322 |
6 | 333 | 335 | 385 | 324 |
7 | 333 | 343 | 250 | 360 |
8 | 332 | 324 | 105 | 341 |
9 | 331 | 315 | 32 | 348 |
10 | 334 | 326 | 14 | 358 |
11 | 333 | 340 | 9 | 331 |
12 | 334 | 330 | 4 | 321 |
13 | 332 | 331 | 1 | 329 |
14 | 332 | 336 | 0 | 320 |
5000 | 5000 | 5000 | 5000 |
30.2. Альтернативы для клиента TCP
Мы уже обсуждали различные способы устройства клиентов, но стоит тем не менее еще раз обратить внимание на относительные достоинства и недостатки этих способов.
1. В листинге 5.4 показан основной способ устройства клиента TCP. С этой программой были связаны две проблемы. Во-первых, когда она блокируется в ожидании ввода пользователя, она не замечает происходящих в сети событий, например отключения собеседника от соединения. Во-вторых, она действует в режиме остановки и ожидания, что неэффективно в случае пакетной обработки.
2. Листинг 6.1 содержит следующую, модифицированную версию клиента. С помощью функции select
клиент получает информацию о событиях в сети во время ожидания ввода пользователя. Однако проблема этой версии заключается в том, что программа не способна корректно работать в пакетном режиме. В листинге 6.2 эта проблема решается путем применения функции shutdown
.
3. С листинга 16.1 начинается рассмотрение клиентов, использующих неблокируемый ввод-вывод.
4. Первым из рассмотренных нами клиентов, вышедшим за пределы ограничений, связанных с наличием единственного процесса или потока для обслуживания всех запросов, является клиент, изображенный в листинге 16.6. В этом случае использовалась функция fork
, и один процесс обрабатывал передачу данных от клиента к серверу, а другой — в обратном направлении.
5. В листинге 26.1 используются два потока вместо двух процессов.
В конце раздела 16.2 мы резюмируем различия между перечисленными версиями. Как мы отметили, хотя версия с неблокируемым вводом-выводом является самой быстродействующей, ее код слишком сложен, а применение двух потоков или двух процессов упрощает код.
30.3. Тестовый клиент TCP
В листинге 30.1[1] показан клиент, который будет использоваться для тестирования всех вариаций нашего сервера.
Листинг 30.1. Код клиента TCP для проверки различных версий сервера
//server/client.с
1 #include "unp.h"
2 #define MAXN 16384 /* максимальное количество байтов, которые могут быть
запрошены клиентом от сервера */
3 int
4 main(int argc, char **argv)
5 {
6 int i, j, fd, nchildren, nloops, nbytes;
7 pid_t pid;
8 ssize_t n,
9 char request[MAXLINE], reply[MAXN];
10 if (argc != 6)
11 err_quit("usage: client
12 "<#loops/child> <#bytes/request>");
13 nchildren = atoi(argv[3]);
14 nloops = atoi(argv[4]);
15 nbytes = atoi(argv[5]);
16 snprintf(request, sizeof(request), "%d\n", nbytes); /* в конце
символ новой строки */
17 for (i = 0; i < nchildren; i++) {
18 if ((pid = Fork()) == 0) { /* дочерний процесс */
19 for (j = 0; j < nloops; j++) {
20 fd = Tcp_connect(argv[1], argv[2]);
21 Write(fd, request, strlen(request));
22 if ((n = Readn(fd, reply, nbytes)) != nbytes)
23 err_quit("server returned %d bytes", n);
24 Close(fd); /* состояние TIME_WAIT на стороне клиента,
а не сервера */
25 }
26 printf("child %d done\n", i);
27 exit(0);
28 }
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии