views:

125

answers:

3

I have created a client-server architecture using Boost Asio.

The entire thing works, I can send and receive messages, etc, so there is no question about the correctness. However, when I implement it in a real network, all of a sudden it becomes VERY slow. When I run the server and client on the same computer itgoes blazingly fast, but when I run it on 2 different computers, it becomes exremely slow, I have to wait a second for each message. And these messages are SMALL maybe 50, 60 characters max. They are sent over correctly though.

The code:

stream = new tcp::iostream(serverIp, portNum); // Clientside

For sending and receiving I use:

(*stream) << data << delimiter;
std::getline(*stream, response, '#');

The server uses the same for sending and receiving, and some setup code for setting up the connection:

boost::asio::io_service io_service;

tcp::endpoint endpoint(tcp::v4(), portNum); 
tcp::acceptor acceptor(io_service, endpoint);

for (;;)
{
    tcp::iostream *stream = new tcp::iostream();
    acceptor.accept(*(stream->rdbuf()));

    // Do stuff with the stream
}

Again, it WORKS, just very slowly allof a sudden on a real network. Is there something I am doing wrong? I tried changing the portNum, didn't work. Anything else I can do?

+1  A: 

If that is the sum total of your send/receive code then it seems like a lot of time will be spent waiting for the sender and receiver to be in sync before the << and getline calls complete. This effect will be amplified greatly when a real network connection is introduced. It may seem blazing fast locally but measure byte throughput locally before assuming this. Typically you would not tightly couple send and receive processing like this - you are basically taking an async I/O library and enforcing it to be sync. Try reworking to actually use async I/O, and decouple send and receive processing from each other (or at least do not serialize them like this using synchronous higher-level I/O calls to access the socket) and performance on the network should improve.

Steve Townsend
How would you suggest doing this? Where should I begin, is this hard to do?
kiri
use async_read and async_write
Cătălin Pitiș
Yes, this is hard to do, but you will be glad you learnt how to do it once you are done. Track down some sample code using Google, understand it (preferably by running it in the debugger), and then rework your design accordingly.
Steve Townsend
A: 

Prepare the data to be sent offline, then use async_write to write the data. Read the data from the socked with async_read. These are non-blocking operations, so it might have significant impact on the server side.

Cătălin Pitiș
A: 

Might not fix it, but worth a try-- change the client to flush the stream after message send:

  (*stream) << data << delimiter << std::flush;
gavinandresen