【发布时间】:2021-06-09 17:58:55
【问题描述】:
我的目标是在 telnet 服务器端使用 C/C++ readline 库,因为它提供了开箱即用的所有必要终端功能。 Readline 已经连接到 telnet 套接字,对套接字的读写工作正常。我正在使用libtelnet by Sean Middleditch。
问题在于 readline 输出 '\n' 而不是 '\n\r' 这是一个 telnet 标准去一个新行 = 新行 + 回车。
客户端的当前输出:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
> example
> another example
> 3rd example
>
预期输出:
Trying 127.0.0.1...
Connected to localhost.
The escape character is '^]'.
> example
> another example
> 3rd example
>
我阅读文档试图找到一个带有默认换行符的简单变量,但没有这样的东西,或者我一定错过了它。这种行为也有可能会随着 telnet 终端类型而改变——我还没有到这一步。
您知道如何将这个 '\n' 更改为 '\r\n' 吗?
编辑:
Telnet 启动 & Readline 连接到套接字:
void startLibTelnet(int connfd)
{
char buffer[512];
int rs;
telnet_t *telnet;
telnet = telnet_init(telopts, _event_handler, 0, &connfd);
// telnet options
telnet_negotiate(telnet, TELNET_DO,
TELNET_TELOPT_LINEMODE);
telnet_negotiate(telnet, TELNET_WILL,
TELNET_TELOPT_ECHO);
telnet_negotiate(telnet, TELNET_WILL,
TELNET_TELOPT_TTYPE);
// redirecting readline input/output to TCP socket
rl_instream = fdopen(connfd, "r");
rl_outstream = fdopen(connfd, "w");
again:
// forever loop
while ( (rs = recv(connfd, buffer, sizeof(buffer), 0)) > 0)
{
telnet_recv(telnet, buffer, rs);
}
if (rs < 0 && errno == EINTR)
goto again;
else if (rs < 0)
perror("str_echo: read error");
}
部分事件处理程序:
static void _event_handler(telnet_t *telnet, telnet_event_t *ev,
void *user_data)
{
int sock = *(int*)user_data;
switch (ev->type) {
/* data received */
case TELNET_EV_DATA:
rl_gets("> ");
break;
/* data must be sent */
case TELNET_EV_SEND:
_send(sock, ev->data.buffer, ev->data.size);
break;
/* request to enable remote feature (or receipt) */
case TELNET_EV_WILL:
break;
/* notification of disabling remote feature (or receipt) */
case TELNET_EV_WONT:
break;
. // here's also
. // case DO
. // case DONT
default:
break;
}
}
我认为我应该保留 readline 模块。最好的解决方案可能是告诉客户端将“\n”或换行解释为“\n\r”或换行和回车。我在查找这种 telnet 选项时遇到问题。
【问题讨论】:
-
\r\n不是标准换行符。 C++ 标准只知道\n。你是如何输出线条的?在使用此类换行符的平台(即 Windows)上,cin在输入时将\r\n规范化为\n,在输出时cout将\n转换为\r\n。请提供minimal reproducible example -
流的打开模式将决定是否翻译换行符。
binary模式下的流将\r\n视为两个字符。当以text模式打开时,\r\n将被视为换行符;\r通常被忽略(作为空格)。 -
@RemyLebeau 问题已更新。我想我需要一个 telnet 选项来告诉客户端将 '\n' 解释为 '\n\r',对吗?
-
我认为 libtelnet 负责使 readline 的 C 标准输出符合 RFC854 - 你只需要指示它这样做。
标签: c++ telnet readline libreadline