powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Linux, accept(), SIGTERM и Ctrl+C
8 сообщений из 8, страница 1 из 1
Linux, accept(), SIGTERM и Ctrl+C
    #34358383
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть небольшая консольная программка под линукс, которая считывает данные, приходящие к ней через сокет, изменяет их и перебрасывает дальше (на прокси).
Работает в бесконечном цикле (фрагмент):
Код: 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
Linux, accept(), SIGTERM и Ctrl+C
    #34358452
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ожидать соединения можно путем прослушивания сокета на чтение селектом. Там можно выставить таймаут.
...
Рейтинг: 0 / 0
Linux, accept(), SIGTERM и Ctrl+C
    #34358488
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может стоит попробовать перехватывать

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

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

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


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

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


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