如何将此Boost ASIO示例应用于我的应用程序
How To Apply This Boost ASIO Example To My Application
我已经读了很多ASIO的例子,但我仍然有点困惑如何在我的应用程序中使用它们。
基本上,我的服务器端需要接受超过100个连接(客户端),这部分是通过使用线程池来完成的(通常每个CPU核心2~4个线程)。
为简单起见,我们假设只有一个连接。
为简单起见,我还想复制示例:http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/nonblocking/third_party_lib.cpp
class session
{
public:
session(tcp::socket&)
bool want_read() const;
bool do_read(boost::system::error_code&);
bool want_write() const;
bool do_write(boost::system::error_code&);
};
class connection : public boost::enable_shared_from_this<connection>
{
public:
typedef boost::shared_ptr<connection> pointer;
static pointer create(boost::asio::io_service&);
tcp::socket& socket();
void start();
private:
connection(boost::asio::io_service&);
void start_operation();
void handle_read(boost::system::error_code);
void handle_write(boost::system::error_code);
}
class server
{
public:
server(boost::asio::io_service&, unsigned short);
private:
void start_accept();
void handle_accept(connection::pointer, const boost::system::error_code&);
}
您可以查看完整的类实现链接。
我要做的是添加读/写操作到类session
(或者我应该直接把它们放在connection
?)
AsyncRead(buffer, expectedBytesToRead, timeout, handler);
Read(buffer, expectedBytesToRead, timeout);
AsyncWrite(buffer, expectedBytesToWrite, timeout, handler);
Write(buffer, expectedBytesToWrite, timeout);
我确实读了很多例子,但对我来说,似乎很难弄清楚如何使用它们,也就是说,在我的应用程序中实现上面4个常见的方法。
我想我已经非常接近我想要的了,我只是不知道从一个非常简单的例子开始。我读的例子@ boost.org,他们要么太复杂,弄清楚逻辑或不是我想要的在我的项目。我建议在您的连接类中保持与套接字的所有通信,使其尽可能保持通用。
你想怎么做,你的选择几乎是无限的。我所做的是将我的"消息处理"类的shared_ptr传递给每个新连接,并像您一样创建一个会话,但我将每个连接的副本传递给会话和所有相关信息。因此,当有新消息传入时,每个单独的会话都可以通知程序,并且我可以在每个会话中存储任何我想要的东西。
当连接终止时,请注意通知会话,因为您现在将它存储在某个地方,而不仅仅是通过回调保持智能指针的活动。
typedef boost::shared_ptr<class Connection> connectionPtr;
void Server::handle_accept(sessionPtr new_connection, const boost::system::error_code& error)
{
if (!error)
{
cout << "New connection detected." << endl;
string sessionID = misc::generateSessionID();
string IPaddress = new_connection->socket().remote_endpoint().address().to_string();
mSessionManager_->AddSession(new_connection, IPaddress, sessionID);
// session manager now has a copy of the connection and
// can reference this by the sessioNID or IPAddress
new_connection->start();
connectionPtr NEWER_CONNECTION(new Connection(_io_service, _loginList, _mMessageHandlerClass));
cout << "Awaiting next connection..." << endl;
acceptor_.async_accept(newer_session->socket(),
boost::bind(&Server::handle_accept, this, NEWER_CONNECTION,
boost::asio::placeholders::error));
}
else
{
new_connection.reset();
}
}
这里只是一个如何处理消息的示例。显然,totalbytesremaining需要从标题中提取,我没有包括在示例中。
void Session::handle_body(const boost::system::error_code& error, size_t bytes_transferred)
if(!error)
{
totalBytesRemaining -= bytes_transferred;
if (totalBytesRemaining == 0)
{
if (incompleteToggle = true)
{
tempMessage+=string(readMsg.body());
messageHandlerClass->Process(sessionID,tempMessage);
tempMessage = "";
tempMessageToggle = false;
}
else
{
tempMessage += string(readMsg.body());
std::cout << "Incomplete receive: This is our message So far.nn" << tempMessage << "n" << endl;
tempMessageToggle = true;
}
}
handle_message();
}
else
{
removeSession();
}
现在我可以从SessionManager类访问所有的session
void SessionManager::listConnectedIP()
{
for (int x = 0; x < sessionBox.size(); x++)
{
cout << sessionBox[x]->IPaddress() << endl;
}
}
void SessionManager::massSendMessage(const std::string &message)
{
for (int x = 0; x < sessionBox.size(); x++)
{
sessionBox[x]->connectionPtr->pushMessage(message);
}
}
处理消息的Connection类是这样的。消息只保留缓冲区,并对报头进行编码和解码。这是我在boost示例网站上发现的另一个修改类。
void Connection::pushMessage(const string& message)
{
// boost async_write will return instantly, but guarantees to
// either error or send all requested bytes.
// there is no need to check if all bytes get sent in the callback.
Message writeMsg;
writeMsg.body_length( strlen(msg.c_str()) );
memcpy( writeMsg.body(), msg.c_str(), writeMsg.body_length() );
writeMsg.encode_header();
boost::asio::async_write(socket_, boost::asio::buffer(writeMsg.data(), writeMsg.length()),
boost::bind(&Session::handle_write, this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
如果我的例子不是很好,我很抱歉。要真正掌握boost::asio及其示例,您确实需要了解异步函数和回调是如何工作的。
- 请找出我的代码中的错误,它在提交得到错误答案的同时仍然适用于我的所有测试用例
- 我可以将c ++清理器仅应用于程序的一部分而不是第三方库吗?
- Visual C++ wxWidgets应用程序仅适用于我的PC
- 模板包扩展以将函数应用于连续的参数对
- 从另一个应用启动我的应用时出现相对路径更改问题
- [expr.unary.op]/9 似乎暗示"运算符!()' 不能应用于下面的类型 A.但编译器不同意这一点
- 仅将方法应用于类的一个对象
- 尝试创建波形着色器,我似乎无法计算法线以将镜面照明应用于我的波形
- 用于将参数应用于函数的模板函数
- 在这种情况下,(N)RVO是否适用于我的功能
- C++有没有办法将函数'simultaneously'应用于向量的所有元素?
- 将功能应用于图像的每个像素
- 设置精度应用于旧的 C 样式代码
- 用C++创建一个写作应用程序(我的第一个项目)(学习C++)
- 要应用于输入的转换链的设计模式
- 如何检查c++stl向量中是否存在值,并将函数应用于向量的每个元素
- 有没有一种更快的方法或优化我可以应用到我的即兴内存池
- 我是否应该将 RAII 应用于我分配的所有阵列
- 使用OpenCV校准了我的相机.如何将输出 xml 中的系数应用于我未来的项目
- 如何将此Boost ASIO示例应用于我的应用程序