5.12. Завершение процесса сервера
5.12. Завершение процесса сервера
Теперь мы запустим соединение клиент-сервер и уничтожим дочерний процесс сервера. Это симулирует сбой процесса сервера, благодаря чему мы сможем выяснить, что происходит с клиентом в подобных ситуациях. (Следует точно различать сбой процесса сервера, который мы рассмотрим здесь, и сбой на самом узле сервера, о котором речь пойдет в разделе 5.14.) События развиваются так:
1. Мы запускаем сервер и клиент на разных узлах и вводим на стороне клиента одну строку, чтобы проверить, все ли в порядке. Строка отражается дочерним процессом сервера.
2. Мы находим идентификатор дочернего процесса сервера и уничтожаем его с помощью программы kill. Одним из этапов завершения процесса является закрытие всех открытых дескрипторов в дочернем процессе. Это вызывает отправку сегмента FIN клиенту, и TCP клиента отвечает сегментом ACK. Это первая половина завершения соединения TCP.
3. Родительскому процессу сервера посылается сигнал SIGCHLD, и он корректно обрабатывается (см. листинг 5.9).
4. С клиентом ничего не происходит. TCP клиента получает от TCP сервера сегмент FIN и отвечает сегментом ACK, но проблема состоит в том, что клиентский процесс блокирован в вызове функции fgets в ожидании строки от терминала.
5. Запуск программы netstat на этом шаге из другого окна на стороне клиента показывает состояние клиентского сокета:
linux % netstat -a | grep 9877
tcp 0 0 *:9877 *:* LISTEN
tcp 0 0 localhost:9877 localhost:9877 FIN_WAIT2
tcp 1 0 localhost.43604 localhost:9877 CLOSE_WAIT
Как видите, согласно рис. 2.4, осуществилась половина последовательности завершения соединения TCP.
6. Мы можем снова ввести строку на стороне клиента. Вот что происходит на стороне клиента (начиная с шага 1):
linux % tcpcli01 127.0.0.1 запускаем клиент
hello первая строка, которую мы ввели
hello она корректно отражается
теперь мы уничтожаем (kill) дочерний процесс
сервера на узле сервера
another line затем мы вводим следующую строку на стороне клиента
str_cli: server terminated prematurely
Когда мы вводим следующую строку, функция str_cli вызывает функцию writen, и TCP клиента отправляет данные серверу. TCP это допускает, поскольку получение сегмента FIN протоколом TCP клиента указывает только на то, что процесс сервера закрыл свой конец соединения и больше не будет отправлять данные. Получение сегмента FIN не сообщает протоколу TCP клиента, что процесс сервера завершился (хотя в данном случае он завершился). Мы вернемся к этому вопросу в разделе 6.6, когда будем говорить о половинном закрытии TCP.
Когда TCP сервера получает данные от клиента, он отвечает сегментом RST, поскольку процесс, у которого был открытый сокет, завершился. Мы можем проверить, что этот сегмент RST отправлен, просмотрев пакеты с помощью программы tcpdump.
7. Однако процесс клиента не увидит сегмента RST, поскольку он вызывает функцию readline сразу же после вызова функции writen, и readline сразу же возвращает 0 (признак конца файла) по причине того, что на шаге 2 был получен сегмент FIN. Наш клиент не предполагает получать признак конца файла на этом этапе (см. листинг 5.3), поэтому он завершает работу, сообщая об ошибке Server terminated prematurely (Сервер завершил работу преждевременно).
ПРИМЕЧАНИЕ
Этапы описанной последовательности также зависят от синхронизации времени. Вызов readline на стороне клиента может произойти до получения им пакета RST от сервера, но может произойти и после. Если readline вызывается до получения RST, происходит то, что мы описали выше (клиент считывает символ конца файла). Если же первым будет получен пакет RST, функция readline возвратит ошибку ECONNRESET (соединение сброшено собеседником).
8. Когда клиент завершает работу (вызывая функцию err_quit в листинге 5.4), все его открытые дескрипторы закрываются.
Проблема заключается в том, что клиент блокируется в вызове функции fgets, когда сегмент FIN приходит на сокет. Клиент в действительности работает с двумя дескрипторами — дескриптором сокета и дескриптором ввода пользователя, и поэтому он должен блокироваться при вводе из любого источника (сейчас в функции str_cli он блокируется при вводе только из одного источника). Обеспечить подобное блокирование — это одно из назначений функций select и poll, о которых рассказывается в главе 6. Когда в разделе 6.4 мы перепишем функцию str_cli, то как только мы уничтожим с помощью программы kill дочерний процесс сервера, клиенту будет отправлено уведомление о полученном сегменте FIN.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
9.1.5. Завершение процесса
9.1.5. Завершение процесса Завершение процесса включает два шага: окончание процесса с передачей системе статуса завершения и восстановление информации родительским
Завершение и прекращение выполнения процесса
Завершение и прекращение выполнения процесса После того как процесс завершил свою работу, он, или, точнее, выполняющийся в этом процессе поток, может вызвать функцию ExitProcess, указав в качестве параметра кодом завершения (exit code): VOID ExitProcess(UINT uExitCode) Эта функция не
Завершение процесса
Завершение процесса Как это ни грустно, но любой процесс в конечном итоге должен завершиться. Когда процесс завершается, ядро должно освободить ресурсы, занятые процессом, и оповестить процесс, который является родительским для завершившегося, о том, что его порожденный
Завершение процесса
Завершение процесса С завершением процесса дело обстоит достаточно просто, по крайней мере, в сравнении с тем, что происходит при завершении потока, как это и будет показано очень скоро. Процесс завершается, если программа выполняет вызов exit() или выполнение просто
Код процесса-сервера (менеджера ресурсов)
Код процесса-сервера (менеджера ресурсов) Для запуска сервера на удаленном узле выполните с терминала команду:# on -f /net/Bed-Test /net/904-3/home/ZZZ/BIN/TestMGRгде Bed-Test — имя удаленного узла, 904-3 — имя локального узла, /home/ZZZ/BIN/TestMGR — путь к исполняемому файлу.Вначале сервер выполняет
Завершение выполнения процесса
Завершение выполнения процесса Процесс завершает свое выполнение с помощью функции exit(). Эта функция может быть вызвана системным вызовом exit(2), а если завершение процесса вызвано получением сигнала, функцию exit() вызывает само ядро. Функция exit() выполняет следующие
Создание, завершение и просмотр учетной записи процесса
Создание, завершение и просмотр учетной записи процесса К другим основным возможностям инструментария управления WMI относятся возможности работы с процессами, запущенными на удаленном или локальном компьютере. При этом инструментарий предоставляет возможности не
Использование сервера Yaffil внутри процесса
Использование сервера Yaffil внутри процесса С точки зрения прикладной программы различие между встраиваемым сервером и обычным удаленным клиентом заключается в имени библиотеки динамической загрузки (DLL), связываемой с программой. Как известно, обычные приложения
Завершение процесса, заблокировавшего ресурс
Завершение процесса, заблокировавшего ресурс Когда взаимное исключение используется совместно несколькими процессами, всегда существует возможность, что процесс будет завершен (возможно, принудительно) во время работы с заблокированным им ресурсом. Не существует
15.11. Досрочное завершение клиента или сервера
15.11. Досрочное завершение клиента или сервера В наших примерах до настоящего момента предполагалось, что в процессе работы клиента и сервера не возникает непредусмотренных ситуаций. Посмотрим, что произойдет, если у клиента или сервера возникнут ошибки. В случае если
Досрочное завершение сервера
Досрочное завершение сервера Если клиент блокируется в вызове door_call, ожидая получения результатов, ему нужно каким-то образом получить уведомление о завершении потока сервера по какой-либо причине. Посмотрим, что происходит в этом случае, прервав работу сервера вызовом
16.7. Досрочное завершение сервера или клиента
16.7. Досрочное завершение сервера или клиента Рассмотрим, что произойдет в случае досрочного завершения клиента или сервера при использовании транспортного протокола TCP. Поскольку протокол UDP не подразумевает установку соединения, при завершении процесса его
Досрочное завершение сервера
Досрочное завершение сервера Завершим работу сервера досрочно, в процессе обработки запроса клиента. Единственное изменение в программе-клиенте будет заключаться в удалении аргумента tcp из вызова clnt_call в листинге 16.2 и включении протокола в набор аргументов командной
Завершение процесса с помощью команды KILL
Завершение процесса с помощью команды KILL В SQL Server администратор может удалить процесс, например пользовательское подключение или блокировку базы данных, с помощью команды KILL. Обычно эта команда применяется для чрезвычайного прекращения пользовательского сеанса,
3.4. Завершение процесса
3.4. Завершение процесса Обычно процесс завершается одним из двух способов: либо выполняющаяся программа вызывает функцию exit(), либо функция main() заканчивается. У каждого процесса есть код завершения — число, возвращаемое родительскому процессу. Этот код передается в