通过telnet发送数据而无需按Enter键

Mat*_*att 13 java sockets terminal telnet

我最近开始搞乱Java套接字和telnet ......

我希望用户能够连接到服务器,只需键入一个字母并将其发送到服务器,而无需按Enter键发送它.我确定服务器没有办法设置它,但也许telnet有一个参数或什么可以允许这个?

也许如果我让用户输入stty cbreakstty raw在运行telnet之前,这可行吗?(仅限UNIX,我知道!)

如果我可以通过telnet来执行此操作,那么我将不得不为此功能编写一个特殊客户端...

Ben*_*son 8

实际上还有就是服务器请求此道:这就是所谓的telnet选项协商.telnet当您在其他端口上使用端口23和"cooked"(或"line")模式时,通常会默认以"原始"模式配置本地tty.行模式是您进行简约本地编辑的地方,当您点击返回时会发送数据.

禁用linemode后,您可以单独配置本地echo等内容.

编辑:我认为合理的顺序是:

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 */
Run Code Online (Sandbox Code Playgroud)

这启用TELOPT_LINEMODE(34)然后将linemode设置LM_MODE0(我认为这是告诉客户端不做任何本地编辑的正确方法).最后它表示WILL ECHO服务器将回显(因此客户端不会).

客户端(如果它支持telnet协商)将回复序列IAC blah blah或"引用"序列IAC SB ... IAC SE,您可以检测并过滤掉输入流.


eat*_*ter 3

您应该能够通过 telnet 选项协商来做到这一点。该协议默认为半双工模式,并且至少对于交互式会话,服务器应协商抑制继续选项回显选项

\n\n

至少,您可以ff fb 01 ff fb 03在会话开始时吐出(将回显,将抑制前进),然后ff fd 01用(将回显)回复任何ff fb 01(执行回显)并回复任何ff fd 03(执行抑制前进)前进)与ff fb 03(将抑制前进)。

\n\n

编辑补充说,本·杰克逊提到的线路模式协商是一个更好的答案。对于大多数在 23 以外的端口上连接的客户端来说,抑制继续是不够的。

\n\n

不过,我认为您遇到的另一个问题是 Java 正在发送 Unicode 字符。例如,当您说 时(char)0xff,Java 假定您指的是 UTF-16 字符,U+00ff\xc3\xbf。它可能使用 UTF-8 编码通过套接字发送,因此 telnet 客户端会看到两个字节:c3 bf它会传递并显示为\xc3\xbf.

\n\n

您可以做的就是明确告诉 Java 使用 ISO-8859-1 编码。例如,您以前可能做过类似的事情:

\n\n
out = new PrintStream(connection.getOutputStream());\nout.print((char)0xff);  // sends 0xc3 0xbf\nout.print((char)0xfb);  // sends 0xc3 0xbb\nout.print((char)0x01);  // sends 0x01\nout.flush();\n
Run Code Online (Sandbox Code Playgroud)\n\n

相反,您可以使用 OutputStreamWriter 来指定所需的编码:

\n\n
out = new OutputStreamWriter(connection.getOutputStream(), "ISO-8859-1");\nout.write((char)0xff);  // sends 0xff\nout.write((char)0xfb);  // sends 0xfb\nout.write((char)0x01);  // sends 0x01\nout.flush();\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我认为您可以同时使用 PrintStream 和 OutputStreamWriter。调用 `out = new PrintStream(conn.getOutputStream());` AND `rawout = new OutputStreamWriter(conn.getOutputStream(), "ISO-8859-1");` 然后你可以做 `rawout.write((char) 0xff);` 发送单个 255 字节,但 `out.print("whatever \u2588");` 发送其他所有内容。 (2认同)