ipwnatlyfe
ipwnatlyfe

Reputation: 11

Data not Sending Until Socket is Closed

I am learning some network programming and was recommended to use boost-asio. I did Daytime Tutorials 1&2 on: http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/tutorial.html and wanted to modify it so that the server reacts to a client sending a serialized object then sends back results. I imagined using something like the following sequence with the intention that the client would sit in the handleRead loop waiting for the server to finish:

Server:
accept --> handleRead --> process_read --> perform action --> handleWrite

Client:
connect --> handleWrite --> handleRead --> process_read

However, when I do this, both the server and the client somehow get stuck in the read loop I have set up. This is expected on the client side, but the client should be writing and sending the data prior to getting to the read loop. When I break the connection on the client side or add a socket.close() to the end of the write function I wrote, all the rest of the server steps take place with the appropriate data having been sent from the client.

I originally thought this issue had to do with Nagle's algorithm being enabled, but adding

boost::asio::ip::tcp::no_delay option(true);
socket.set_option(option);

Didn't help at all. Am I missing something that wasn't in the tutorial as to how to get this data to send such as flushing the socket?

void myClient::handle_read()
{
    boost::system::error_code e;
    try
    {       
        for (;;)
        {
            size_t len = boost::asio::read(socket, boost::asio::buffer(inBuffer), e);

            std::cout << "Client Received: ";

            if (e == boost::asio::error::eof)
            {
                break;
            }

            else if (e)
            {
                throw boost::system::system_error(e);
            }
        }
    }

    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        std::cout << e.what() << std::endl;
    }
}

template <typename T>
void handleWrite(T& t)
{
    std::ostringstream archive_stream;
    std::string tempString;

    boost::archive::text_oarchive archive(archive_stream);
    archive << t;

    tempString = archive_stream.str();
    outBuffer.assign(tempString.begin(), tempString.end());

    boost::system::error_code ignored_error;
    size_t sent = boost::asio::write(socket, boost::asio::buffer(outBuffer), ignored_error);
    std::cout << sent << std::endl;
}

I'm fairly new to c++ and network programming so any additional documentation is also appreciated. Thanks!

Upvotes: 1

Views: 1038

Answers (1)

user207421
user207421

Reputation: 310840

Of course you're stuck in your read loop. It doesn't exit until end of steam, and end of stream only happens when the peer closes the socket.

Upvotes: 1

Related Questions