【问题标题】:Losing characters in TCP Telnet transmissionTCP Telnet 传输中的字符丢失
【发布时间】:2011-10-24 05:55:11
【问题描述】:

我正在使用 Winsock 通过 Telnet 发送命令;但是由于某种原因,当我尝试发送字符串时,偶尔会丢失一些字符。我用send:

int SendData(const string & text)
{   
send(hSocket,text.c_str(),static_cast<int>(text.size()),0);
Sleep(100);
send(hSocket,"\r",1,0); 
Sleep(100);
return 0;
}

有什么建议吗?


更新:

我检查了,即使发送了所有字符,错误仍然存​​在。所以我决定更改Send 函数,让它发送单个字符并检查它们是否已发送:

void SafeSend(const string &text)
{       
   char char_text[1];
   for(size_t i = 0; i <text.size(); ++i) 
   {
      char_text[0] = text[i];
      while(send(hSocket,char_text,1,0) != 1);
   }
}

此外,它以一种特殊的方式丢弃字符;即在句子的中间。例如

set variable [fp]exit_flag = true

发送为

 ariable [fp]exit_flag = true

或者

set variable [fp]app_flag = true

发送为

setrable [fp]app_flag = true
 

【问题讨论】:

  • 为什么不检查send()的返回值?
  • 来自MSDN: "如果没有出错,send返回发送的总字节数,可以小于len参数中请求发送的字节数 。” (我的重点)
  • @Alex:我已经更新了我的问题

标签: c++ windows telnet tcpclient


【解决方案1】:

正如 cmets 中提到的,您绝对需要检查 send 的返回值,因为它可以在仅发送一部分缓冲区后返回。

您几乎总是希望在类似于以下的循环中调用send(未测试,因为我目前没有可用的 Windows 开发环境):

 bool SendString(const std::string& text) {
      int remaining = text.length();
      const char* buf = text.data();
      while (remaining > 0) {
           int sent = send(hSocket, buf, remaining, 0);
           if (sent == SOCKET_ERROR) {
                /* Error occurred check WSAGetLastError() */
                return false;
           }
           remaining -= sent;
           buf += sent;
      }
      return true;
 }

更新: 这与 OP 无关,但对 recv 的调用也应采用与上述相同的方式。

为了进一步调试问题,Wireshark(或等效软件)非常适合追踪问题的根源。

过滤您想要查看的数据包(它有很多选项)并检查它们是否包含您认为它们包含的内容。

另请注意,telnet 是一个包含大量RFCs 的协议。大多数情况下,您只需发送原始文本就可以侥幸逃脱,但并不能保证它确实有效。

您提到 Windows telnet 客户端向您发送不同的字节,从两个客户端捕获最小序列并比较它们。使用 RFC 找出其他客户端的不同之处以及原因。您可以使用“查看 -> 数据包字节”来调出数据包的数据,并且可以轻松地检查和复制/粘贴十六进制转储。

【讨论】:

  • 我已经修改了我的Send 函数,但我仍然有问题
  • @Jacob: 1) 你的safeSend 不安全,因为它会在出错时进入无限循环。 2)您写道所有数据都已发送,您是否使用例如Wireshark? 3)我可以在你原来的例子中看到你发送'\r',通常你想在一行的末尾发送"\r\n"
  • 我发现这取决于我发送字符的速度。如果我将每个字符的传输延迟任意数量,它似乎可以工作。有什么办法可以绕过它(即最小延迟)?
  • @Jacob:你用什么来接收数据?你确定它工作正常吗? recv 的使用方式与 send 相同 - 在接收端听起来很像同样的问题。
  • 很有可能。我在另一端有一个运行 Telnet 服务器的 FANUC 机器人。我通过查看日志来检查收到的消息的状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多