我希望telnet客户端将中断/信号作为正常的ASCII值传递给服务器。
我在代码中从服务器向客户端发送以下telnet命令。
IAC SB LINEMODE TRAPSIG 0 IAC SE
sprintf(msg, "%c%c%c%c%c%c%c", 255 /*IAC*/, 250 /*SB*/, 34 /*LINEMODE*/,
2 /*TRAPSIG*/, 0 /*mask*/, 255 /*IAC*/, 240 /*SE*/);
但是在telnet提示符下按Ctrl + c,客户端仍然传递telnet命令而不是ASCII值。
服务器收到的消息: IAC IP IAC DO 6(时间标记)
我想接收ctrl + C(3)。而不是“IAC IP”。
任何想法如何让客户端发送ASCII值而不是telnet命令,而服务器从telnet客户端收到整行而不是逐个字符。
任何帮助都将受到高度赞赏!
答案 0 :(得分:1)
您的谈判LINEMODE
似乎不正确。
对于尚未与IAC
或SB
进行协商或未进行过协商的选项,您无法突然发送WILL
DO
分别以DO
或WILL
回复。
特别是对于线路模式,根据RFC 1184,服务器端应该只启动IAC
DO
LINEMODE
(而不是WILL
)。< / p>
然后,它会等待客户回复IAC
WILL
LINEMODE
或IAC
WONT
LINEMODE
。在后一种情况下,你无能为力,因为客户端不愿意在此时支持线路模式,随后发送子协商将毫无意义(一致的客户端将忽略它)。
如果客户使用IAC
WILL
LINEMODE
回复了您的请求,则表示会进行线路模式的进一步细分协商,但通常会由客户端,而不是您(服务器)。
这意味着您现在应该等待客户端发送IAC
SB
LINEMODE
个IAC
SE
个帖子,并对此提出请求<{1}}和MODE
作为子选项。
特别是,您希望在客户端请求FORWARDMASK
,因为这是客户端仅发送完整行的实际模式,更重要的是您要请求{ {1}}在客户端中被关闭,因为捕获信号意味着客户端拦截有问题的按键并将其转换为Telnet命令(例如EDIT
TRAPSIG
),你不想要。那就是:
IAC
IP
IAC
SB
1 LINEMODE
MODE
(1表示IAC
开启且SE
关闭。)
并且您还想协商一个EDIT
,其中设置了与您希望接收的控制字符相关联的所有位,否则您将仅在客户端发送完成的行时才接收这些字符,甚至根本不接收。
对于Ctrl-C(ASCII 3),最小前向掩码请求将是:
TRAPSIG
FORWARDMASK
IAC
SB
LINEMODE
16 DO
FORWARDMASK
(16是十进制的。请注意,这些位是从 MSB开始计算的,而不是LSB ,如果您不知道它,可能会造成混淆。)
然后你必须等待客户端同时确认模式和前向掩码。如果客户端先前已同意协商线路模式,则客户端必须遵守服务器对IAC
和SE
设置的请求(但是,这并不能保证它会将特殊键传递给你),但可以自由拒绝前方面具。
最后,如果您希望客户端成功与您协商所需的选项,您需要确保尽可能地保持协议。我建议您至少阅读并理解section 5.10 of the RFC中的示例通信。