The client sends about 165 KB of data to the server. At first everything is fine. But when the client sends the same data again (165 KB), I get a server-side approval. Assert contains information about an "iterator beyond borders"
The call stack has some information about the read_until method. Therefore, I think I made a mistake.
The asynchronous TCP server code is below:
Code for handle_read :
void Session::handle_read(const boost::system::error_code& a_error, size_t a_nbytestransferred) { if (!a_error) { std::ostringstream dataToRetrive; dataToRetrive << &m_bufferRead; boost::thread threads(boost::bind(retriveMessageFromClient, shared_from_this(), dataToRetrive.str())); boost::asio::async_write(m_socket, m_bufferWrite, boost::bind(&Session::handle_write, shared_from_this(), boost::asio::placeholders::error)); } else disconnect(); }
Code for handle_write :
void Session::handle_write(const boost::system::error_code& a_error) { if (!a_error) { boost::asio::async_read_until(m_socket, m_bufferRead, boost::regex(G_strREQUESTEND), boost::bind(&Session::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else disconnect(); }
Both m_bufferRead, m_bufferWrite are members of the Session class.
class Session... boost::asio::streambuf m_bufferRead; boost::asio::streambuf m_bufferWrite;
Update
I found that the problem lies elsewhere in my code. After completing the finishing tasks, metdhod do_writeMessage () is called.
Stream function
void retriveMessageFromClient(boost::shared_ptr<Session>& A_spSesion, std::string A_strDataToRetrive) { try { std::string strAnswer; bool bFind = (A_strDataToRetrive.find(G_REGEX_BIG_FILE_BEGIN) != std::string::npos); if(bFind) // Write large data to osFile { A_strDataToRetrive = boost::regex_replace(A_strDataToRetrive, boost::regex(G_REGEX_BIG_FILE_BEGIN), std::string("")); std::string strClientFolder = str(boost::format("%1%%2%") % CLIENT_PRE_FOLDER_FILE % A_spSesion->getIdentifier()); std::string strClientFile = str(boost::format("%1%\\%2%%3%") % strClientFolder % strClientFolder % CLIENT_EXTENSION); if ( boost::filesystem::exists(strClientFolder) ) boost::filesystem::remove_all(strClientFolder); else boost::filesystem::create_directory( strClientFolder ); std::ofstream osFile(strClientFile.c_str()); osFile << A_strDataToRetrive; osFile.close(); strAnswer = str(boost::format(G_FILE_WAS_WRITE) % strClientFile); } else { double dResult = sin (30.0 * 3.14/180); strAnswer = str(boost::format(G_OPERATION_RESULT) % dResult); } // Sleep thread boost::xtime timeToSleep; boost::xtime_get(&timeToSleep, boost::TIME_UTC); timeToSleep.sec += 2; boost::this_thread::sleep(timeToSleep); A_spSesion->do_writeMessage(strAnswer); } catch (std::exception& e) { std::cerr << THREAD_PROBLEM << e.what() << "\n"; } }
Do_writeMessage session
void Session::do_writeMessage(const std::string& A_strMessage) { m_strMessage = A_strMessage; m_strMessage += G_strRESPONSEEND; // m_socket.send(boost::asio::buffer(m_strMessage)); It works correctly m_socket.async_send(boost::asio::buffer(m_strMessage), boost::bind(&Session::handle_write, shared_from_this(), boost::asio::placeholders::error)); -- after that assert }
So I have a problem with asynch_send ...
UPDATED
**TCPAsyncServer**::TCPAsyncServer(boost::asio::io_service& A_ioService, short port, : m_ioService(A_ioService), m_lIDGenerator(0), m_clientSocket(m_ioService, tcp::endpoint(tcp::v4(), port)), { SessionPtr newSession(new Session(m_ioService, m_mapSessions, ++m_lIDGenerator)); m_clientSocket.async_accept(newSession->getSocket(), boost::bind(&TCPAsyncServer::handle_ClientAccept, this, newSession, boost::asio::placeholders::error));
Session Contractor
Session::Session(boost::asio::io_service& A_ioService, std::map<long, boost::shared_ptr<Session> >& A_mapSessions, long A_lId) : m_socket(A_ioService), m_mapSessions(A_mapSessions), m_lIdentifier(A_lId), m_ioService(A_ioService) {}
Members of the session
std::map<long, boost::shared_ptr<Session> >& m_mapSessions; long m_lIdentifier; boost::asio::ip::tcp::socket m_socket; boost::asio::io_service& m_ioService;