In our application, we use the Boost libraries (and ASIO for network communications).
Recently, we have found that if we send our data from different streams through the same socket, our client application receives garbage data.
A small test to highlight the problem:
#include <stdio.h> #include <boost/thread.hpp> #include <boost/asio.hpp> void send_routine(boost::shared_ptr<boost::asio::ip::tcp::socket> s, char c) { std::vector<char> data(15000, c); data.push_back('\n'); for (int i=0; i<1000; i++) boost::asio::write(*s, boost::asio::buffer(&data[0], data.size())); } int main() { using namespace boost::asio; using namespace boost::asio::ip; try { io_service io_service; io_service::work work(io_service); const char* host = "localhost"; const char* service_name = "18000"; tcp::resolver resolver(io_service); tcp::resolver::query query(tcp::v4(), host, service_name); tcp::resolver::iterator iterator = resolver.resolve(query); auto socket = boost::shared_ptr<tcp::socket>(new tcp::socket(io_service)); socket->connect(*iterator); boost::thread t1(send_routine, socket, 'A'); boost::thread t2(send_routine, socket, 'B'); boost::thread t3(send_routine, socket, 'C'); t1.join(); t2.join(); t3.join(); } catch (std::exception& e) { printf("FAIL: %s\n", e.what()); } return 0; }
So, we create a socket here, connect to localhost:18000 and start 3 threads that will be written to the socket.
In another terminal window, I run nc -l -p 18000 | tee out.txt | sort | uniq | wc -l nc -l -p 18000 | tee out.txt | sort | uniq | wc -l nc -l -p 18000 | tee out.txt | sort | uniq | wc -l . I expect 3 as output, but it returns more than 100 "different lines" in the network stream (so the data is corrupted). But it works with small buffer sizes (if we change 15000 to 80 , for example).
So the question is, is this behavior of the ASIO library correct? And one more thing: how to fix it? Should I use mutex inside my send_routine function (or is there another solution)?