Сокеты POSIX: Как обнаружить Ctrl-C, отправленный через Telnet? - PullRequest
5 голосов
/ 10 июня 2010

Короткий вопрос
Как правильно обрабатывать событие Ctrl-C, отправляемое через Telnet на стороне сервера?

Длинный вопрос
После вызова recv () для сокета я бы хотел обработать некоторые ситуации соответствующим образом. Один из них - вернуть определенный код ошибки при получении Ctrl-C. Какой правильный способ обнаружить это? Следующее работает, но это не кажется правильным:

size_t recv_count;
static char ctrl_c[5] = {0xff, 0xf4, 0xff, 0xfd, 0x06};

recv_count = recv(socket, buffer, buffer_size, 0);

if (recv_count == sizeof(ctrl_c) &&
    memcmp(buffer, ctrl_c, sizeof(ctrl_c) == 0)
{
    return CTRL_C_RECEIVED;
}

Я нашел комментарий к Ctrl-C в примечании в этом FAQ по сокету UNIX:

[...] (кстати, внеполосное часто используется и для этого ctrl-C).

Как я понимаю, получение внеполосных данных осуществляется с использованием recv () с определенным флагом в качестве последнего параметра. Но когда я жду данных с использованием recv (), как в приведенном выше коде, я не могу одновременно читать внеполосные данные. Кроме того, я получаю что-то , используя recv () без этого флага oob.

1 Ответ

2 голосов
/ 10 июня 2010

Установите сокет для неблокирования с помощью fcntl (), используйте select () (pselect () в некоторых системах), чтобы проверить поступающие данные. Вот как можно проверить текущее состояние сокета, то есть, есть ли у него данные для recv () и если он может принять send (), или есть исключение. Не просто сидеть там, блокируя.

Функция recv () возвращает столько доступной информации, сколько может вместить размер предоставленного буфера. Если сокет был настроен на получение внеполосных данных (опция сокета SO_OOBINLINE) и имеются непрочитанные данные OOB, возвращаются только внеполосные данные. Вызовите ioctl () SIOCATMARK, чтобы определить, остаются ли еще какие-либо внеполосные данные непрочитанными.

Когда вы получаете данные OOB, вы не можете выполнить recv () после окончания пакета OOB в одном вызове recv (), поэтому в этом отношении это доказательство.

Я не знаю, что считается наилучшей практикой, но идея использовать ctrl-c перед другими уже буферизованными данными сокетов - хорошая идея.

...