我正在使用follow函数使用telnet发送和接收数据。但是收到的数据被截断了几百个字符。为什么会发生这种情况?我该如何解决这个问题?我怀疑,数据没有从另一端“足够快”发送,我的代码认为这是telnet流的结束。如果是这种情况,我怎样才能使接收等待足够长的时间?
std::string sendTelnet(std::string str)
{
const int default_buflen = 512;
const char *loopback_address = "127.0.0.1";
std::string retval;
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char recvbuf[default_buflen];
int iResult;
int recvbuflen = default_buflen;
for(int i=0; i<default_buflen; i++)
{
recvbuf[i] = '\0';
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
std::cerr<<"WSAStartup failed with error: " + iResult;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(loopback_address, std::to_string((long double)jtagTerminalPort).c_str(), &hints, &result);
if ( iResult != 0 ) {
std::cerr<<"getaddrinfo failed with error: " + iResult;
WSACleanup();
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
std::cerr<<"socket failed with error: " + WSAGetLastError();
WSACleanup();
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
std::cerr<<"Unable to connect to server!\n";
WSACleanup();
}
// Send an initial buffer
iResult = send( ConnectSocket, str.c_str(), (int)strlen(str.c_str()), 0 );
if (iResult == SOCKET_ERROR) {
std::cerr<<"send failed with error: " + WSAGetLastError();
closesocket(ConnectSocket);
WSACleanup();
}
//telnet_bytes_sent = iResult;
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
{
//telnet_bytes_received = iResult;
}
} while( iResult == 0 );
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
std::cerr<<"shutdown failed with error: " + WSAGetLastError();
closesocket(ConnectSocket);
WSACleanup();
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
retval = recvbuf;
Sleep(100);
return retval;
}
PS。截断数据的意思是 retval 返回实际通过telnet发送的截断版本。例如,如果从另一端发送的数据是“1,2,3,...,1000”,则在功能结束时, retval 将仅持有“1,2,3,......,300”。
编辑:在应用程序中,我通过telnet发送一些命令并等待响应。然后,我接收响应并相应地运行一些功能。然后我通过telnet发送下一组命令,并等待响应。等等...
答案 0 :(得分:1)
你的do / while循环条件错误。它应该是while (iResult > 0)
。但是你应该将它重写为while
循环,以避免双重测试。
答案 1 :(得分:1)
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
{
//telnet_bytes_received = iResult;
}
} while( iResult == 0 );
这是一种非常复杂的方法,可以从套接字中读取512个字节(如果它已被关闭,则永远阻止)。
这应该是这样的:
// Receive until the peer closes the connection
while ((iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0)) > 0)
{
retval.append(recvbuf, iResult);
}
这将从套接字读取,直到它关闭或发生错误,并且每次都将收到的数据附加到返回字符串。