怎样应用这个升压ASIO示例我的应用程序 [英] How To Apply This Boost ASIO Example To My Application

查看:107
本文介绍了怎样应用这个升压ASIO示例我的应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过很多例子ASIO,但我仍然对如何在我的应用程序中使用它们几分困惑。

I've been reading a lot of ASIO examples, but I'm still sort of confused on how to use them in my application.

基本上,我的服务器端需要接受超过100个连接(客户端),这部分是通过使用线程(通常为2〜4个线程每个CPU核心)。

Basically, my server side needs to accept more than 100 connections (clients), this part is done by using a pool of threads (usually, 2~4 threads for each CPU core).

为了简单起见,我们只是假设只存在一个连接。

For simplicity, let's just assume there is only one connection.

,我也想这个例子中复制:<一href=\"http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/nonblocking/third_party_lib.cpp\" rel=\"nofollow\">http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/nonblocking/third_party_lib.cpp

For simplicity, I would also like to copy the example from: 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&);
}

您可以检查链接的完整的类实现。

You can check the link for the complete class implementations.

我试图做的是为读/写操作加入到类会议(或者我应该直接把它们放在连接?)

What I'm trying to do is to add for read/write operations into class session (or should I directly put them in connection?)

AsyncRead(buffer, expectedBytesToRead, timeout, handler);
Read(buffer, expectedBytesToRead, timeout);
AsyncWrite(buffer, expectedBytesToWrite, timeout, handler);
Write(buffer, expectedBytesToWrite, timeout);

我也看了很多的例子,但在我看来,这是非常困难的弄清楚如何使用它们,即落实在我的应用上述4个常用的方法。

I did read a lot of examples, but it seems to me that it's very difficult to figure out how to use them, i.e., implement the above 4 common methods in my application.

我想我非常接近我想要什么,我只是不想在这里从一个很简单的例子开始。我读@ boost.org的例子,他们要么过于复杂找出逻辑还是不是我想要在我的项目。

I guess I'm very close to what I want, I just don't where to start from a very simple example. The example I read @ boost.org, they are either too complicated to figure out the logic or not what I want in my project.

推荐答案

我建议将所有你的沟通与您的连接类插座,保持尽可能通用。

I would suggest keeping all of your communication with the socket in your connection class, keeping it as generic as possible.

您的选择是你想如何做到这一点几乎是无限的。我要做的就是通过我的信息处理类的shared_ptr的每一个新的连接,也可以创建一个会话像你这样做,但我通过每个连接的会话和所有相关信息的副本以及..所以每个单独的会话当一个新的消息进来可以通知程序,我可以存储任何东西我想在每一个会话。

Your options are almost limitless on how you want to do it. What I do is pass a shared_ptr of my "Message Handling" class to each new Connection and also create a Session like you do, but I pass a copy of each Connection to the Session and all relevant info as well.. so each individual session can notify the program when a new message comes in, and I can store anything else I want in each Session.

只是要小心你的通知时,会话连接终止,因为你现在保存它的地方,而不是只保留智能指针通过回调活着。

Just be careful about notifying your Sessions when the Connection terminates, since you are now storing it somewhere and not only keeping the smart pointer alive via call-backs.

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需要从标题,我没有在例子包括被提取出来。

Here's just an example of how to handle a message. Obviously totalbytesremaining needs to be extracted from the header, which I didn't include in examples.

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.\n\n" << tempMessage << "\n" << endl;
                tempMessageToggle = true;
            }

        }

    handle_message();
    }
else
{
    removeSession();
}

所以,现在我已经从是SessionManager类访问我的所有会话

So now I have access to all my Sessions from the SessionManager class

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);
    }
}

和处理邮件的连接类是这样的。消息只是持有C $ CS和德codeS头中的缓冲和连接$。这是另一种改进的I类升压例如网站上找到。

And the Connection class for handling messages is something like this. Message just holds the buffer and encodes and decodes the header. It's another modified class I found on the boost example website.

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));
}

很抱歉,如果我的例子不是很好。为了获得提振:: ASIO和他们的榜样的真实把握,你真的需要了解功能和回调如何异步工作方式。

Sorry if my examples aren't very good. To get a real grasp of boost::asio and their examples, you really need to understand how asynchronous functions and callbacks work.

这篇关于怎样应用这个升压ASIO示例我的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆