客戶端向服務器發送約165kB的數據。起初一切都很好。 但是當客戶端再次發送相同的數據(165kB)時,我收到服務器端的斷言。 Assert包含有關「迭代器越界」的信息boost :: asio :: streambuf斷言「迭代器出界」
在調用堆棧上,有一些關於read_until
方法的信息。 所以我認爲我犯了一個錯誤。
TCP異步服務器代碼如下:
代碼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();
}
代碼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();
}
兩個m_bufferRead,m_bufferWrite是一流的會議成員。
class Session...
boost::asio::streambuf m_bufferRead;
boost::asio::streambuf m_bufferWrite;
更新
我檢測到的問題在其他地方我的代碼奠定。 比線程完成任務後,調用do_writeMessage()metdhod 。
線程函數
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
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
}
所以finnally我有asynch_send一個問題...
修訂
名**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::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)
{}
會議成員
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;
我已經合併,這一個您未註冊的帳戶,您可以編輯您的問題。另外,我將你留下的答案和你的問題合併在一起。 – 2011-03-12 11:38:58
@Lehu你爲什麼要在handle_read中啓動一個線程? – 2011-03-12 14:02:09
我的任務是:當我從客戶端收到消息時,我必須在新線程中檢索此消息,並且在線程完成工作時,應發送消息給客戶端。 – Lehu 2011-03-12 14:17:26