Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Linux, accept(), SIGTERM и Ctrl+C / 8 сообщений из 8, страница 1 из 1
27.02.2007, 17:03
    #34358383
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux, accept(), SIGTERM и Ctrl+C
Есть небольшая консольная программка под линукс, которая считывает данные, приходящие к ней через сокет, изменяет их и перебрасывает дальше (на прокси).
Работает в бесконечном цикле (фрагмент):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
void mainLoop(const sockaddr_in& proxyAddr){
	fprintf(stderr, "main loop started\n");
	while (running){
		sockaddr_in srcAddr;
		socklen_t len = sizeof(srcAddr);
		SOCKET incoming = accept(input, (sockaddr*)&srcAddr, &len);
		if (incoming == INVALID_SOCKET){
			int errorNum = errno;
			if (errorNum == EINTR)
				continue;
			fprintf(stderr, "Cannot accept request, error index: %d\n", errorNum);
			break;
		}

		fprintf(stderr, "new connection.\n");
		
/*
..
*/
	}
	fprintf(stderr, "main loop completed\n");
}
Для корректного завершения нужно перехватить сигнал завершения приложения или Ctrl+C.
Как я понял по манам, это SIGTERM и делается это, например, так.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void sigHandler (int sigNum){
	running = false;
}
//...
	struct sigaction sa;
	memset(&sa,  0 , sizeof(sa));
	sa.sa_handler = sigHandler;
	sigaction(SIGTERM, &sa,  0 );
//...

Однако, возникают 3 проблемы:
1) Судя по всему, sigHandler никогда не вызывается, и программа завершается сразу, молча, на предоставляя возможности культурно освободить используемыз сокет.
2) accept() будет ждать входящих соединений. Если их не будет, то программа повиснет (пока ей не придет SIGKILL). Как это исправить? Кинуть нолик на TCP порт самому себе? Или есть другие варианты?
3) есть используемые программой (и ей же созданные thread'ы). И там аналогичная ситуация - используются функции для сокетов, которые могут ожидать соединения. Как поступить? Плюнуть, в расчете что рано или поздно будет CONNECTION_TIMEOUT и thread завершится или можно как-то прервать ожидание входящих данных?

Как лучше поступить?
...
Рейтинг: 0 / 0
27.02.2007, 17:22
    #34358452
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux, accept(), SIGTERM и Ctrl+C
Ожидать соединения можно путем прослушивания сокета на чтение селектом. Там можно выставить таймаут.
...
Рейтинг: 0 / 0
27.02.2007, 17:32
    #34358488
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux, accept(), SIGTERM и Ctrl+C
Может стоит попробовать перехватывать

Код: plaintext
1.
signal(SIGINT, sigHandler);

?
...
Рейтинг: 0 / 0
27.02.2007, 19:27
    #34358838
A. Fig Lee
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux, accept(), SIGTERM и Ctrl+C
AkhОжидать соединения можно путем прослушивания сокета на чтение селектом. Там можно выставить таймаут.

ето если сокет уже есть - после accept().
угу, ловить SIGINT надо, моно еще несколько.
...
Рейтинг: 0 / 0
27.02.2007, 19:50
    #34358876
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux, accept(), SIGTERM и Ctrl+C
Спасибо, буду пробовать.
...
Рейтинг: 0 / 0
28.02.2007, 00:58
    #34359157
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux, accept(), SIGTERM и Ctrl+C
С SIGINT заработало, спасибо огромное. :)
...
Рейтинг: 0 / 0
28.02.2007, 09:40
    #34359472
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux, accept(), SIGTERM и Ctrl+C
A. Fig Lee AkhОжидать соединения можно путем прослушивания сокета на чтение селектом. Там можно выставить таймаут.
ето если сокет уже есть - после accept().
...


Открытый сокет прослушивается селектом на чтение, именно для чтения. :)

Если сокет помечен листеном, то в данном случае селект на чтение, говорит о том, что можно делать ассепт.
...
Рейтинг: 0 / 0
28.02.2007, 09:41
    #34359477
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Linux, accept(), SIGTERM и Ctrl+C
man accept
Для того, чтобы получать уведомления о входящих подключениях на сокете, вы можете использовать select(2) или poll(2).
В этом случае, когда придет запрос на новое соединение, будет полученособытие "можно читать", и тогда вы можете вызват
ь accept, чтобы получить сокет для этого соединения. В другом случае, вы можете заставить сокет передавать си г н а л
SIGIO, когда он активируется; см. socket(7) для уточнения подробностей.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Linux, accept(), SIGTERM и Ctrl+C / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]