我正在研究基于ncurses通过telnet导出文本用户界面的程序。 当我使用硬编码值时,这基本上有效:
fd = accept(sfd, NULL, 0); // tcp socket to client
FILE *fh = fdopen(fd, "rw");
SCREEN *scr = newterm("vt100", fh, fh);
setterm(scr);
resizeterm(25, 80);
// ...regular ncurses code...
在ncurses中,您使用getch()来检索按键。这将自动将特殊字符(如光标键 - 向上/向下/等)(ESC [A等)转换为常量,如KEY_UP。
Telnet使用特殊的字节码将终端窗口大小,终端类型等参数传递给telnet-client,反之亦然。
如果我想摆脱这些硬编码值,我需要发送telnet代码,但我还需要收到他们的回复。
我现在的问题是:这些telnet代码是否会干扰ncurses?我能使用getch()还是会误解ncurses代码中的特殊字符?
答案 0 :(得分:1)
开始的地方是RFC:RFC 854 - TELNET PROTOCOL SPECIFICATION表示字符255
(0xff
, IAC )是保留给客户端和服务器之间的通信。
RFC(理论)和实践(实现)之间存在脱节。编写RFC的意图是仅支持简单的电传打字替换(即,没有光标寻址,根本没有转义序列)。从RFC的角度来看,一旦你开始考虑终端(大多数可用的终端,当1983年发布的RFC确实支持游标寻址时),除了小心不发送(未转义的)字符{{}之外,没什么可说的。 1}}。
RFC 854在2008年被RFC 5198 - Unicode Format for Network Interchange更新(未过时)。与RFC 854一样,它假设每个人都使用玻璃电传打字,建议不使用退格字符导致其不同系统上的行为可能不同。 RFC中的一个有用的注释表明字符255不是有效的UTF-8字符串的一部分。
如果您不使用UTF-8,ISO-8859-x编码可能会发送255.它是一个有效的可打印字符。除非您的数据恰好包含该字符,否则ncurses不会发送该字符,但ncurses没有特殊规定来转义字符。
ncurses假设您的通信路径是8位干净的。 RFC 856 - TELNET BINARY TRANSMISSION解决了部分问题, IAC 的 Achilles heel 未触及:
有效的二进制传输选项,接收器应该 解释从发射机接收的字符不是 前面带有
255
作为8位二进制数据,IAC
除外 其次是IAC,代表8位二进制数据 十进制值255。IAC
后跟有效的 TELNET 命令(加上 完成命令所需的任何其他字符仍然是 即使二进制传输选项生效,该命令也是如此。的IAC
强> 后跟一个不是已定义的 TELNET 命令的字符 与IAC
后跟IAC
的含义相同,但NOP
后跟 通常不应在此模式下发送未定义的命令。
您当然可能遇到一些真正的8位清理实现,但它不符合RFC。