【问题标题】:receiving from remote server giving junk characters?从远程服务器接收垃圾字符?
【发布时间】:2014-07-31 03:40:56
【问题描述】:

我正在尝试编写一个 telnet 客户端来连接到以下服务器:

198.182.241.14(主办方:美国堪萨斯州匹兹堡州立大学)-登录:图书馆

我已通过以下代码成功连接;

sd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sin;
memcpy(&sin.sin_addr.s_addr, host->h_addr, host->h_length);
sin.sin_family = AF_INET;
sin.sin_port = htons(portno);
if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
    printf("error .. connecting sockets\n");
    return bRet;
}
printf("connected...\n");

然后我将“库”作为密码发送(据我所知,我必须输入硬编码密码)

但是在接收时,我得到了一些垃圾字符:,在下一次接收时它被绞死了:

char buf[2048] = {0};
send(sd, command, strlen(command),0);
send(sd, (void*)"\n",2,0);

这里的命令是“库”

这发送了 7 个字节,但之后我的例外是从服务器接收一些数据:

**PSU 图书馆联盟 - 选择要搜索的图书馆 1. PSU Axe 图书馆目录 ......还有更多*

我通过以下代码接收:

while(1)
{
    memset(buf, 0, 2048);
    int rv = recv(sd , buf , 2048 , 0);
    printf("received %d\n",rv);
    if (rv < 0)
        return false;
    else if (rv == 0) {
        printf("Connection closed by the remote end\n\r");
        return 0;
    }
    buf[rv] = '\0';
    printf("%s\n",buf);
    for(int i =0;i<strlen(buf);i++)
    {
        printf("%c = %d = 0x%08x\n",buf[i], buf[i], buf[i]);
    }
}

这是打印一些垃圾字符如下:

ÿýÿý ÿý#ÿý'
ÿ = -1 = 0xffffffff
ý = -3 = 0xfffffffd
 = 24 = 0x00000018
ÿ = -1 = 0xffffffff
ý = -3 = 0xfffffffd
  = 32 = 0x00000020
ÿ = -1 = 0xffffffff
ý = -3 = 0xfffffffd
# = 35 = 0x00000023
ÿ = -1 = 0xffffffff
ý = -3 = 0xfffffffd
' = 39 = 0x00000027
received 0
Connection closed by the remote end

有什么帮助吗?

更多编辑:任何好的文章/书籍参考/完整的代码示例 - 这样我就可以从套接字编程开始并通过密码成功登录 telnet 服务器

非常感谢提前

【问题讨论】:

  • 垃圾字符长什么样?如果您正在连接到远程登录服务器,那么您应该阅读 RFC854,也许您正在接收远程登录控制数据?另外:仅仅发送用户名是不够的,你需要一个行尾来终止登录名。
  • @WernerHenze 它看起来像这样:ÿýÿý ÿý#ÿý' ....我不确定我在哪里犯了错误,或者我错过了一些东西,试图修复。我是 telnet/socket 编程的新手,所以我需要查看那些 telnet 控制数据?我现在通过 send(sd, (void*)'\0', 1, 0) 发送 EOL 谢谢
  • 请提供数据的二进制转储,而不是 ASCII 转储。 (void*)'\0' 不是你想要的(实际上这只是 NULL),你需要一个 在字符串的末尾,所以“\n”(或“\r\n”)。
  • @WernerHenze 添加了二进制转储并更新了原始帖子:谢谢
  • 发送“\n”时请只发送一个字节。 '\n' 是一个字符,即换行符。您可以使用 strlen("\n") 进行检查。如果您发送两个字符,您将发送 '\n' 和尾随的空字节。您不想发送尾随空字节。

标签: c++ c linux telnet


【解决方案1】:

当您连接到远程登录服务器时,您必须遵守远程登录协议。虽然 telnet 连接可能看起来像纯文本发送/接收,但它实际上是一个额外的协议。每次收到 0xff 时,这就是一个 telnet 转义码。一些案例:

  • 0xff 0xff = 0xff 数据字节的转义
  • 0xff 0xfd = DO,后跟选项代码

因此,在您的情况下,服务器会向您发送 DO(TerminalType=0x18)、DO(TerminalSpeed=0x20)、DO(XDisplayLocation0x23) 和 DO(NewEnvironmentOption=0x27)。您应该使用 WILL(...) 或 WONT(...) 进行响应。无论如何,要获得真实数据,您必须过滤掉 telnet 协议部分。

这里有一些有趣的链接:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多