我正在使用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);
}
}
此外,它以一种特殊的方式丢弃字符;即在句子的中间。 E.g。
set variable [fp]exit_flag = true
以
发送 ariable [fp]exit_flag = true
或者
set variable [fp]app_flag = true
以
发送setrable [fp]app_flag = true
答案 0 :(得分:2)
正如评论中所提到的,你绝对需要检查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来确定其他客户端的不同之处以及原因。您可以使用“查看 - &gt;数据包字节”来显示数据包的数据,并可以轻松检查和复制/粘贴十六进制转储。