[英]boost::asio tcp server disconnect issue
我目前正在使用boost :: asio TCP套接字編寫一個TCP服務器。 我使用了提供的示例,通過將套接字對象包裝在我自己的會話對象中,使服務器變為全狀態。
除斷開連接外,一切正常。 在我的設置中,我總是為每個打開的套接字調用async_read_some 。
正常行為是當我連接客戶端並斷開連接時。 調用數據讀取處理程序並設置了錯誤,因此我知道套接字已斷開連接。
不良行為是當我以一個順序連接2個客戶端並以相同順序關閉它們時。 當我關閉第一個客戶端時,沒有任何處理程序被調用,但是當我關閉第二個客戶端時,我也獲得了第一個客戶端的調用,兩者均通知斷開連接。
除此問題外,其他所有功能似乎都運行良好。 在多個客戶端上發送和接收數據工作正常。
有人遇到過這個問題嗎? 這可能是什么原因?
bool TCPNetworkListener::StartListener()
{
//check if already started
if (m_SocketAcceptor.is_open())
{
return false;
}
//create the socket acceptor
m_SocketAcceptor.open(m_TCPEndpoint.protocol());
m_SocketAcceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
m_SocketAcceptor.bind(m_TCPEndpoint);
m_SocketAcceptor.listen();
//accept async connections
m_lastConnectedClientId++;
TCPNetworkSession::SharedPtr new_session(new TCPNetworkSession(m_IOService, this, m_lastConnectedClientId));
m_SocketAcceptor.async_accept(new_session->GetSocket(),
boost::bind(&TCPNetworkListener::HandleNewConnection, this, new_session,
boost::asio::placeholders::error));
//all fine
m_listenerState = NetworkListener::NLState_Running;
return true;
}
void TCPNetworkListener::HandleNewConnection( TCPNetworkSession::SharedPtr session, const boost::system::error_code& error )
{
if (error)
{
return;
}
session->StartNewSession();
//accept new async connections
m_lastConnectedClientId++;
TCPNetworkSession::SharedPtr new_session(new TCPNetworkSession(m_IOService, this, m_lastConnectedClientId));
m_SocketAcceptor.async_accept(new_session->GetSocket(),
boost::bind(&TCPNetworkListener::HandleNewConnection, this, new_session,
boost::asio::placeholders::error));
}
該會話如下所示:
TCPNetworkSession::TCPNetworkSession( boost::asio::io_service& io_service , TCPNetworkListener* handler, long clientId) :
m_socket(io_service),
m_IOService(io_service),
m_networkHandler(handler),
m_clientId(clientId),
m_sendingData(false)
{
}
tcp::socket& TCPNetworkSession::GetSocket()
{
return m_socket;
}
void TCPNetworkSession::StartNewSession()
{
//notify of new connection established
if (m_networkHandler)
{
m_networkHandler->ClientConnected(shared_from_this());
}
m_socket.set_option(boost::asio::socket_base::keep_alive(true));
//try to read the first message data
m_socket.async_read_some(
boost::asio::buffer(m_readBuffer, SOCKETBUFFERLENGTH),
boost::bind(&TCPNetworkSession::HandleReadData, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
void TCPNetworkSession::HandleReadData( const boost::system::error_code& error, std::size_t bytes_transferred )
{
if (error)
{
//we have got disconnected
if (m_networkHandler)
{
m_networkHandler->ClientDisconnected(shared_from_this());
}
return;
}
//we received new data
if (m_networkHandler)
{
m_readBuffer[bytes_transferred] = 0;
std::string strData(reinterpret_cast<const char*>(m_readBuffer), bytes_transferred);
m_networkHandler->ClientDataReceived(shared_from_this(), strData);
}
//try to read the next message data
m_socket.async_read_some(
boost::asio::buffer(m_readBuffer, SOCKETBUFFERLENGTH),
boost::bind(&TCPNetworkSession::HandleReadData, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
問題出在膩子上。 我使用它來使用telnet測試服務器並根據需要復制會話。 膩子中似乎有一個錯誤,當您關閉會話窗口時,該錯誤會導致套接字無法關閉。 僅當最后一次膩子會話關閉時,套接字才會關閉。
謝謝大家提供的幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.