У меня очень простой TCP-сервер, написанный на C. Он работает бесконечно, ожидая соединений. В Windows я использую select
для проверки активности сокета, и если его нет, у меня есть следующий код, позволяющий мне выйти, нажав q на клавиатуре:
if ( kbhit() ) {
char c = getch();
if ( c == 'q' ) break;
}
Это не работает в unix, поскольку kbhit
не существует, а getch
работает иначе. Я нашел образец кода, который использует tcsetattr
для изменения настроек терминала и позволяет вводить символы посимвольно. После вызова функции init я открываю / dev / stdin (с O_NONBLOCK
) и читаю символ, но read( f, &c, 1 )
блокируется до тех пор, пока не будет достигнут символ.
Я полагаю, я мог бы создать отдельный поток и заставить Это ждать неопределенно долго, а затем сигнализировать первому потоку, если пользователь нажимает «q», но это кажется немного жестким. Неужто есть способ попроще?
Добавьте stdin в свой список дескрипторов выбора, и если у него есть данные, вызовите read, чтобы прочитать из него один символ.
Лучше добавьте "f" из вашего
read( f, &c, 1 )
для выбора звонка. Когда f готов к чтению, символ был нажат, и read () не будет блокироваться.
В Unix, будь то на системной консоли или в окне X-терминала, ввод-вывод с клавиатуры проходит через виртуальный терминал. В наши дни устройство / dev / tty - это обычный способ доступа к управляющему терминалу процесса. Все манипуляции с устройством, кроме открытия / закрытия / чтения / записи, обрабатываются системным вызовом ioctl (2) для этого конкретного устройства. Общее представление о том, что вы хотите сделать, таково:
Откройте управляющий терминал (который может быть, а может и не быть стандартным вводом)
Измените режим работы на этом терминале, чтобы вернуться, не дожидаясь полной строки ввода (что является нормальным значением по умолчанию)
Продолжайте выполнение остальной части вашей программы, зная, что чтение с этого терминала (который может быть стандартным вводом) может возвращать частичные строки или даже нулевые символы, не являясь ошибкой или условием завершения.
Подробный ответ о том, как сделать второй шаг, можно найти в C-программирование: часто задаваемые вопросы. Они также указывают, что это вопрос ОС, а не языка. Они предоставляют девять возможностей, но три основных, имеющих отношение к этому вопросу, следующие:
После пары ссылок в C FAQ можно найти эта страница фрагментов кода kbhit.
Даже если мое приложение еще не использует select, это сработает. Тот факт, что я уже использую select, очень упрощает эту задачу и работает как шарм. Спасибо