java 无需按 Enter 即可通过 telnet 发送数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4532344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:47:48  来源:igfitidea点击:

Send data over telnet without pressing enter

javasocketsterminaltelnet

提问by Matt

I've recently started messing around with Java sockets and telnet...

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

I want the user to be able to connect to the server, just type a letter and have it sent to the server, without pressing enter to send it. I'm sure there's no way for the server to set this up, but maybe telnet has a parameter or something which could allow this?

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

Maybe if I got the user to type stty cbreakor stty rawbefore running telnet, this would work? (UNIX only, I know!)

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

If I can get telnet to do this then it saves me having to write a special client just for this feature...

如果我能让 telnet 做到这一点,那么我就不必为此功能编写一个特殊的客户端了......

采纳答案by eater

You should be able to do this with telnet option negotiation. The protocol defaults to half-duplex mode, and at a minimum for an interactive session, the server should negotiate the suppress go ahead optionand echo option.

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

At the bare minimum you could just spit out ff fb 01ff fb 03(will echo, will suppress-go-ahead) at the begining of the session, then reply to any ff fd 01(do echo) with ff fb 01(will echo) and reply to any ff fd 03(do suppress-go-ahead) with ff fb 03(will suppress-go-ahead).

至少你可以ff fb 01ff fb 03在会话开始时吐出(将回声,将抑制继续),然后ff fd 01ff fb 01(将回声)回复任何ff fd 03(回声)并回复任何(抑制-继续)前进)与ff fb 03(将抑制-前进)。

Editto add that the linemode negotiation mentioned by Ben Hymanson is a better answer. Suppress go-ahead won't be enough for most clients connecting on ports other than 23.

编辑补充说 Ben Hymanson 提到的 linemode 协商是一个更好的答案。对于大多数连接到 23 以外的端口的客户端来说,抑制继续是不够的。

However I think the other problem you're running into is that Java is sending Unicode characters. For example, when you say (char)0xff, Java assumes you're referring to UTF-16 character U+00ffwhich is ?. It's probably sending it over the socket using UTF-8 encoding, so the telnet client sees two bytes: c3 bfwhich it passes on and displays as ?.

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

What you can do is explicitly tell Java to use ISO-8859-1 encoding. For example, you may have been doing something like this before:

您可以做的是明确告诉 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();

Instead, you can use the OutputStreamWriter to specify the encoding you want:

相反,您可以使用 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();

回答by Ben Hymanson

There actually isa way for the server to request this: It's called telnet option negotiation. Typically telnetwill default to configure the local tty in "raw" mode when you use port 23 and "cooked" (or "line") mode on other ports. Line mode is where you have minimalistic local editing and the data is sent when you hit return.

服务器实际上一种方法来请求这个:它被称为telnet 选项协商telnet当您在其他端口上使用端口 23 和“cooked”(或“line”)模式时,通常会默认将本地 tty 配置为“原始”模式。行模式是您进行极简本地编辑的地方,并在您按回车键时发送数据。

Once you disable linemode you can separately configure things like local echo.

禁用 linemode 后,您可以单独配置诸如本地回声之类的内容。

EDIT: I think a reasonable sequence would be:

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

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 */

That enables TELOPT_LINEMODE(34) and then sets the linemode LM_MODEto 0(which I think is the right way to tell the client not do to any local editing). Finally it says WILL ECHOindicating the server will echo (so the client will not).

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

The client (if it supports telnet negotiation) will reply with sequences like IAC blah blahor "quoted" sequences like IAC SB ... IAC SEwhich you can detect and filter out of your input stream.

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

回答by thkala

You need to see the documentation (e.g. manual page) for your telnet client.

您需要查看 telnet 客户端的文档(例如手册页)。

For example mine (krb5-1.6 telnet implementation on Linux) has a mode charactercommand that turns off local line buffering and sends most characters immediately.

例如,我的(Linux 上的 krb5-1.6 telnet 实现)有一个mode character命令可以关闭本地行缓冲并立即发送大多数字符。

EDIT:

编辑:

Disabling Local line editing in some other clients, such as PuTTY, has the same result. PuTTY also has a rawconnection mode that might be of use.

在某些其他客户端(例如 PuTTY)中禁用本地行编辑具有相同的结果。PuTTY 还有一种raw可能有用的连接模式。

Please note that if you don't mind implementing some parts of the TELNET protocol on the server, you can also disable Local line editing (the LINEMODE TELNET option) remotely.

请注意,如果您不介意在服务器上实现 TELNET 协议的某些部分,您还可以远程禁用本地线路编辑(LINEMODE TELNET 选项)。

If you do not care about interactivity you could also use netcat:

如果你不关心交互性,你也可以使用 netcat:

echo -n X | nc host 7777

Unfortunately on many systems (such as mine) netcat uses line-buffered I/O.

不幸的是,在许多系统(例如我的)上,netcat 使用行缓冲 I/O。

回答by Eric Fortis

My advise is to use netcatfor that purposes. It can behave like instant messenger, without pressing enter. searching for netcat tutorial returns tons of videos.

我的建议是为此目的使用netcat。它可以像即时通讯工具一样运行,无需按 Enter。搜索 netcat 教程会返回大量视频。

回答by Néstor Waldyd

To configure telnet to send data without pressing enter, you should disable the line mode option. This is done via the mode telnet subcommand:

要配置 telnet 以在不按 Enter 键的情况下发送数据,您应该禁用线路模式选项。这是通过 mode telnet 子命令完成的:

telnet> mode character

This enables the character at a time mode.

这将启用字符时间模式。