Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.09.2012, 06:45   #1
GrayGhost
Новичок
Джуниор
 
Регистрация: 08.09.2012
Сообщений: 2
По умолчанию Завершение приложения при ожидании accept()

Доброго времени суток.
Столкнулся со следующей проблемой. Пишу сервер. Есть слушающий сокет, при поступлении запроса от клиента создается дочерний процесс, который и обрабатывает клиента. Но при завершении дочернего процесса, завершается и родительский.
Если убрать обработку сигнала, все нормально, но остаются зомби, если оставить один accept() а после него бесконечный цикл, то так же все работает. Я так понял приложение завершается из-за обработки сигнала во время ожидания accept(). Ниже приведен код. Собственно вопрос, что я не так сделал?

Код:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

//Обработчик сигнала от дочернего процесса
void child_handler(int i){
	int status;
	wait(&status);
}

//Функция выполняется дочерним процессом
void child_process(int sd){
 	//делаем что-то полезное
 	sleep(5);
 	close(sd);
	exit(0);
};

int main(int argc, char * argv[]){
	struct sigaction sa;
	struct sockaddr_in addr;
	int sock, l_sock;
	int res;
	
//Установка обработчика на событие дочернего процесса
	sa.sa_handler = child_handler;
	sigaction(SIGCHLD, &sa, 0);
//---------------------------------------------------
	
	l_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (l_sock < 0){
		perror("Создание сокета");
		return 1;
	}
	
	addr.sin_family = AF_INET;
	addr.sin_port = htons(3121);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	if (bind(l_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0){
		perror("bind");
		return 1;
	}
	
	listen (l_sock, 64);
	
	while(1){
		sock = accept(l_sock, NULL, NULL);
		
		res = fork();
 		switch (res){
 			case -1:
 				perror("fork");
 				break;
 			case 0:
 				child_process(sock);
 				break;
 		}
	}
}
GrayGhost вне форума Ответить с цитированием
Старый 15.10.2012, 12:06   #2
Unmanner
Пользователь
 
Регистрация: 18.03.2011
Сообщений: 47
По умолчанию

Я считаю что не нужно никаких обрабтчиков. Ты явно даешь дочернему процессу понять что он должен завершиться с кодом 0.

У тебя обработчик "child_handler" дернется только тогда когда потомок умрет, спрашивается, чего ты будешь ждать в wait()?

ставь wait() сразу после fork(), с проверкой на родительский процесс.
Unmanner вне форума Ответить с цитированием
Старый 17.10.2012, 05:33   #3
GrayGhost
Новичок
Джуниор
 
Регистрация: 08.09.2012
Сообщений: 2
По умолчанию

После смерти потомка, в системе остается зомби, функция wait() в обработчике этого зомби убирает. В результате при частом подключении клиентов, список процессов не засоряется записями о несуществующих процессах.
На счет wait() после fork() не совсем понял. Ведь если я поставлю wait() после fork() в родительском процессе он остановится пока дочерний процесс не завершиться, и сервер не сможет принять еще одного клиента
GrayGhost вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Безусловное завершение работы приложения Aleksandr_59 Общие вопросы Delphi 6 13.04.2012 20:53
Pipe,завершение приложения Скарам Помощь студентам 3 31.03.2010 12:56
завершение цикла при нажатии клавиши LLIyPI/IK Общие вопросы C/C++ 8 12.02.2010 13:29
Завершение приложения lenivec Общие вопросы Delphi 16 05.01.2008 15:23
Завершение приложения, вместе с ОС John_chek Общие вопросы Delphi 5 08.06.2007 16:00