Reputation: 4273
I am trying to connect to an IRC server (twitch.tv). The connection is successful but I don't know how to read the response from the server properly. More specifically I have trouble in this line: boost::asio::read(s, boost::asio::buffer(reply, MAX_LENGTH));
.
If I use MAX_LENGTH
(1024), which is a number larger than the size of the response message then the program doesn't seem to terminate. If I use a number like 64, I can read only 64 characters of the message. Can I somehow read until \r\n
or something ? How can I do this properly ?
#include <boost/asio.hpp>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
try
{
char HOSTNAME[] = "irc.chat.twitch.tv";
char PORT[] = "6667";
char PASS[] = "PASS oauth:123\r\n";
char NICK[] = "NICK 123\r\n";
char USER[] = "USER 123\r\n";
const size_t MAX_LENGTH = 1024;
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket s(io_service);
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::connect(s, resolver.resolve({HOSTNAME, PORT}));
cout << "connected\n";
boost::asio::write(s, boost::asio::buffer(PASS, strlen(PASS)));
boost::asio::write(s, boost::asio::buffer(NICK, strlen(NICK)));
boost::asio::write(s, boost::asio::buffer(USER, strlen(USER)));
cout << "sent 3 messages\n";
char reply[MAX_LENGTH];
size_t reply_length = boost::asio::read(s,
boost::asio::buffer(reply, MAX_LENGTH));
// execution never reaches here
std::cout << "Reply is: ";
std::cout.write(reply, reply_length);
std::cout << "\n";
}
catch (std::exception &e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
Upvotes: 0
Views: 1516
Reputation: 111
I am not familiar with IRC protocol but from a quick look at the RFC it looks like it is text based. In that case I would suggest using boost::asio::read_until for the response.
If you decide that this fits your problem, please keep in mind that read_until internally might read bytes from the incoming stream beyond the specified delimiter. So pay close attention when extracting data from the provided streambuf (you need to use the value returned from read_until).
Have a look at the documentation: http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/read_until/overload3.html
Upvotes: 4
Reputation: 36503
Read tries to read until the buffer is full before returning. If you want the function to return after having read anything at all use read_some.
s.read_some(boost::asio::buffer(reply, MAX_LENGTH));
Upvotes: 1