There are several problems with your code. Most importantly, if getaddrinfo()
fails, you are progressing to the rest of the code, which will crash since result
is invalid. And also, you are ignoring the return values of send()
and recv()
. And you are not actually outputting the data you receive.
Try something more like this:
int _tmain(int argc, _TCHAR* argv[])
{
WSAData wsaData;
int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (res != 0)
{
std::cerr << "failed to init Winsock, error " << res << std::endl;
return 1;
}
addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
addrinfo* result;
res = getaddrinfo("192.168.56.101", "23", &hints, &result);
if (res != 0)
{
std::cerr << "failed to getaddrinfo, error " << res << std::endl;
WSACleanup();
return 1;
}
SOCKET sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (sock == INVALID_SOCKET)
{
res = WSAGetLastError();
std::cerr << "failed to create socket, error " << res << std::endl;
freeaddrinfo(result);
WSACleanup();
return 1;
}
if (connect(sock, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR)
{
res = WSAGetLastError();
std::cerr << "failed to connect, error " << res << std::endl;
freeaddrinfo(result);
closesocket(sock);
WSACleanup();
return 1;
}
freeaddrinfo(result);
std::cout << "connected";
std::string cmd = "md c:\testfolder
";
const char *buf = cmd.c_str();
int size = cmd.length();
do
{
res = send(sock, buf, size, 0);
if (res == SOCKET_ERROR)
{
res = WSAGetLastError();
std::cerr << "failed to send, error " << res << std::endl;
closesocket(sock);
WSACleanup();
return 1;
}
buf += res;
size -= res;
}
while (size > 0);
char out[255];
while (true)
{
res = recv(sock, out, sizeof(out), 0);
if (res == SOCKET_ERROR)
{
res = WSAGetLastError();
std::cerr << "failed to recv, error " << res << std::endl;
closesocket(sock);
WSACleanup();
return 1;
}
if (res == 0)
{
std::cout << "disconnected" << std::endl;
break;
}
std::cout.write(out, res);
}
closesocket(sock);
WSACleanup();
return 0;
}
Now, if you are connecting to an actual Telnet server, not just an arbitrary TCP server running on the standard Telnet port, then you need to implement the actual Telnet protocol. That means handling and responding to Telnet commands (WILL
, WONT
, etc), negotiating Telnet options (message buffer size, charset support, etc), and so on. Everything that is described in RFC 854, and other related RFCs. It may be hard to read (not really), but you need to read and understand it. The "garbage" you receive from the server is likely not garbage at all. It is Telnet commands you are not interpreting yet.
In a nutshell, Telnet commands are escaped, so you have to process the received data byte-by-byte, and if you encounter the escape byte 0xFF
then the next byte is the command type, and depending on what that command is, there may be further bytes to complete the command. Everything else that is not a command is just raw data.