我正在尝试使用boost::asio
构建异步服务器。
服务器是只读的,需要具有会话超时:如果会话超过N秒而没有 接收数据,会话断开连接,客户端需要再次启动连接。
SocketServer.hpp
class SocketServer {
public:
SocketServer(boost::asio::io_service& service);
virtual ~SocketServer();
void StartAsync(int port);
void StopAsync();
private:
void StartAccept();
void HandleAccept(std::shared_ptr<SocketSession> session, const boost::system::error_code& errorCode);
boost::asio::io_service &ioService;
boost::asio::ip::tcp::acceptor acceptor;
};
SocketServer.cpp
SocketServer::SocketServer(boost::asio::io_service& service) :
ioService(service),
acceptor(service) {}
SocketServer::~SocketServer() {}
void SocketServer::StartAsync(int port)
{
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), port);
acceptor.open(ep.protocol());
acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor.bind(ep);
StartAccept();
}
void SocketServer::StopAsync()
{
acceptor.cancel();
}
void SocketServer::StartAccept()
{
std::shared_ptr<SocketSession> session = std::shared_ptr<SocketSession>(new SocketSession(ioService));
acceptor.listen();
acceptor.async_accept(session->getSessionSocket(), boost::bind(&SocketServer::HandleAccept, this, session, boost::asio::placeholders::error));
}
void SocketServer::HandleAccept(std::shared_ptr<SocketSession> session, const boost::system::error_code& errorCode)
{
std::stringstream ss;
if (errorCode)
{
std::cout << "Error accepting incoming connection: Error: " << boost::system::system_error(errorCode).what();
}
else
{
ss << "Connection accepted from address " << socket.remote_endpoint().address().to_string() << ".";
session->start();
}
StartAccept();
}
SocketSession.hpp
#define MAX_BUFFER_LENGTH 1024
class SocketSession {
public:
SocketSession(boost::asio::io_service& service);
virtual ~SocketSession();
void start();
void startTimeoutHandler();
void HandleRead(size_t bytesTransferred, const boost::system::error_code& errorCode);
boost::asio::ip::tcp::socket& getSessionSocket();
private:
boost::asio::ip::tcp::socket sessionSocket;
char readBuffer[MAX_BUFFER_LENGTH];
boost::asio::deadline_timer readTimeout;
void TimeoutHandler(const boost::system::error_code& errorCode);
};
SocketSession.cpp
SocketSession::SocketSession(boost::asio::io_service& service) :
sessionSocket(service),
readTimeout(service) {}
SocketSession::~SocketSession() {}
void SocketSession::start()
{
startTimeoutHandler();
sessionSocket.async_read_some(boost::asio::buffer(readBuffer, MAX_BUFFER_LENGTH), boost::bind(&SocketSession::HandleRead, this, boost::asio::placeholders::bytes_transferred, boost::asio::placeholders::error));
}
void SocketSession::startTimeoutHandler()
{
readTimeout.expires_from_now(boost::posix_time::seconds(10));
readTimeout.async_wait(boost::bind(&SocketSession::TimeoutHandler, this, boost::asio::placeholders::error));
}
void SocketSession::HandleRead(size_t bytesTransferred, const boost::system::error_code& errorCode)
{
std::stringstream ss;
readTimeout.expires_from_now(boost::posix_time::seconds(10));
if (errorCode)
{
std::cout << "Error reading data for session: Error: " << boost::system::system_error(errorCode).what();
delete this;
}
else
{
std::string data(readBuffer, bytesTransferred);
std::cout << "Data read:" << data << std::endl;
}
start();
}
{
return sessionSocket;
}
void SocketSession::TimeoutHandler(const boost::system::error_code& errorCode)
{
delete this;
}
编译好,
我的问题是会话加载后会返回以下错误:
Error: Operation canceled
上的SocketSession::HandleRead
。
它认为boost :: bind不像我的std::shared_ptr
。我尝试了将其更改为普通指针的版本,服务器工作正常。
所以,这是我的问题:
是否可以使用boost::bind
处理std::shared_ptr
?
如果是,我是否以正确的方式做到了?
在没有收听客户端的情况下,可能导致我的代码退出的原因是什么?