Отправлять данные по telnet без нажатия кнопки enter
Недавно я начал возиться с сокетами Java и telnet...
Я хочу, чтобы пользователь мог подключиться к серверу, просто введите письмо и отправьте его на сервер, не нажимая "enter", чтобы отправить его. Я уверен, что нет никакого способа для сервера установить это, но возможно telnet имеет параметр или что-то, что может это позволить?
Может быть, если я попрошу пользователя набрать stty cbreak
или stty raw
перед запуском telnet, это сработает? (Только в UNIX, я знаю!)
Если я смогу заставить telnet сделать это, это избавит меня от необходимости писать специальный клиент только для этой функции...
Ответы
Ответ 1
Вы должны иметь возможность сделать это с помощью согласования опций telnet. По умолчанию протокол используется для полудуплексного режима и, как минимум, для интерактивного сеанса, сервер должен согласовать параметр подавить вариант и вариант эха.
На начальном этапе вы можете просто выплюнуть ff fb 01
ff fb 03
(будет эхо, будет подавлять-вперед) в начале сеанса, а затем ответить на любой ff fd 01
(do echo) с ff fb 01
(будет эхо) и ответить на любой ff fd 03
(do suppress-go-вперед) с ff fb 03
(будет подавлять-вперед).
Отредактируйте, чтобы добавить, что переговоры по linemode, упомянутые Ben Jackson, являются лучшим ответом. Подавление перехода не будет достаточным для большинства клиентов, подключающихся к портам, отличным от 23.
Однако я думаю, что другая проблема, с которой вы сталкиваетесь, заключается в том, что Java отправляет символы Unicode. Например, когда вы говорите (char)0xff
, Java предполагает, что вы имеете в виду символ UTF-16 U+00ff
, который равен ÿ
. Вероятно, он отправляет его через сокет, используя кодировку UTF-8, поэтому клиент telnet видит два байта: c3 bf
, который он передает и отображается как ÿ
.
Что вы можете сделать, это явно указать Java на использование кодировки ISO-8859-1. Например, вы, возможно, раньше делали что-то вроде этого:
out = new PrintStream(connection.getOutputStream());
out.print((char)0xff); // sends 0xc3 0xbf
out.print((char)0xfb); // sends 0xc3 0xbb
out.print((char)0x01); // sends 0x01
out.flush();
Вместо этого вы можете использовать OutputStreamWriter для указания нужной кодировки:
out = new OutputStreamWriter(connection.getOutputStream(), "ISO-8859-1");
out.write((char)0xff); // sends 0xff
out.write((char)0xfb); // sends 0xfb
out.write((char)0x01); // sends 0x01
out.flush();
Ответ 2
На самом деле сервер может запросить это: он назвал согласование опций telnet. Обычно telnet
по умолчанию настраивает локальный tty в "сыром" режиме, когда вы используете порт 23 и "приготовленный" (или "линейный" ) режим на других портах. Режим линии - это то, где у вас минималистичное локальное редактирование, и данные отправляются при нажатии на возврат.
Как только вы отключите linemode, вы можете отдельно настроить такие вещи, как локальное эхо.
EDIT: Я думаю, что разумная последовательность:
255, 253, 34, /* IAC DO LINEMODE */
255, 250, 34, 1, 0, 255, 240 /* IAC SB LINEMODE MODE 0 IAC SE */
255, 251, 1 /* IAC WILL ECHO */
Что позволяет TELOPT_LINEMODE
(34), а затем устанавливает linemode LM_MODE
в 0
(который, я думаю, является правильным способом сообщить клиенту, что он не делает никакого локального редактирования). Наконец, он говорит WILL ECHO
, указывающий, что сервер будет эхо (поэтому клиент не будет).
Клиент (если он поддерживает переговоры по telnet) будет отвечать такими последовательностями, как IAC blah blah
или "кавычки", такие как IAC SB ... IAC SE
, которые вы можете обнаружить и отфильтровать из вашего входного потока.
Ответ 3
Для вашего клиента telnet вам необходимо просмотреть документацию (например, страницу руководства).
Например, моя (реализация krb5-1.6 telnet в Linux) имеет команду mode character
, которая отключает буферизацию локальной строки и отправляет большинство символов сразу.
EDIT:
Отключение Редактирование локальной линии у некоторых других клиентов, таких как PuTTY, имеет тот же результат. PuTTY также имеет режим соединения raw
, который может быть полезен.
Обратите внимание, что если вы не возражаете реализовать некоторые части протокола TELNET на сервере, вы также можете удаленно отключить редактирование локальной линии (опция LINEMODE TELNET).
Если вы не заботитесь об интерактивности, вы также можете использовать netcat:
echo -n X | nc host 7777
К сожалению, во многих системах (таких как мой) netcat использует линейно-буферизованный ввод-вывод.
Ответ 4
Могу посоветовать использовать netcat для этих целей. Он может вести себя как мгновенный мессенджер, не нажимая enter. поиск учебника netcat возвращает массу видео.
Ответ 5
Чтобы настроить Telnet для отправки данных без нажатия клавиши Enter, вам следует отключить опцию режима линии. Это делается с помощью подкоманды mode telnet:
telnet> mode character
Это позволяет персонажу в режиме времени.