I’m trying to learn boost::asio for socket/networking programming. I’m trying to send some simple data from the client to the server.
Let me say first of all that I am intentionally using synchronous, blocking code, as opposed to asynchronous, non-blocking code, because I’m using multithreading (with the pthreads library) in addition to this.
The client is successfully calling boost::asio::write(). I’ve gone so far as to not only try and catch any exceptions thrown by boost::asio::write(), but to also check the boost::system::error_code value, which gives a message “The operation has been completed successfully” or something to that effect.
My read() code looks like this:
#define MAX_MESSAGE_SIZE 10000 // in bytes
void* receivedData = malloc(MAX_MESSAGE_SIZE);
try
{
boost::asio::read(*sock, boost::asio::buffer(receivedData, MAX_MESSAGE_SIZE));
}
catch (std::exception &e)
{
std::cout << "Exception thrown by boost::read() in receiveMessage(): " << e.what() << "\n";
delete receivedData;
receivedData = NULL;
return false;
}
Despite write() being successfully executed on the other end, and both client and server agreeing that a connection has been established at this point, read() never returns. The only case in which it returns for me is if I manually close the client application, at which point (as one would expect), the read() call throws an exception stating that the client has forcibly closed the connection.
Does it have anything to do with io_service.run()? In my googling to debug this, I ran across some mentions of run(), and what I’ve implicitly gathered from those posts is that run() processes the “work”, which I take to mean that it does the actual sending and receiving, and that write() and read() are just means of queuing up a send and checking for what packets have already been sent in and “approved”, so to speak, by io_service.run(). Please correct me if I’m wrong, as the Boost documentation says little more than “Run the io_service’s event processing loop.”
I’m following the boost::asio tutorial ( http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/tutorial/tutdaytime1.html ) which makes absolutely no mention of run(), so maybe I’m completely on the wrong track here and run() isn’t necessary at all?
Either way, just now I made another change to my code to see if anything would change (it didn’t): in both my client and server, I set up a thread for the following function (to call io_service.run() repeatedly throughout the application’s duration to see if not doing so is what was causing the problem):
void* workerThread(void* nothing)
{
while(1)
{
io_service.run();
Sleep(10); // just keeping my CPU from overheating in this infinite loop
}
}
But as stated above, that didn’t affect the performance at all.
What am I missing here? Why is read() never returning, even after the other end’s write() has been executed successfully?
Thanks in advance.
Note that the read you are using will block until the buffer is full or an error occurs – so it will only return when it has received 10000 bytes.
Consider using read_some or using a completion condition with read instead.