<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    boost.asio系列――socket編程

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    asio的主要用途還是用于socket編程,本文就以一個tcp的daytimer服務為例簡單的演示一下如何實現同步和異步的tcp socket編程。

    客戶端

    客戶端的代碼如下:

        #include <iostream>
        #include <boost/array.hpp>
        #include <boost/asio.hpp>

        using boost::asio::ip::tcp;

        int main(int argc, char* argv[])
        {
            try
            {
                boost::asio::io_service io_service;
                tcp::endpoint end_point(boost::asio::ip::address::from_string("127.0.0.1"), 3200);

                tcp::socketsocket(io_service);
                socket.connect(end_point);

                for (;;)
                {
                    boost::array<char, 128> buf;
                    boost::system::error_code error;

                    size_t len = socket.read_some(boost::asio::buffer(buf), error);

                    if (error == boost::asio::error::eof)
                        break; // Connection closed cleanly by peer.
                    else if (error)
                        throw boost::system::system_error(error); // Some other error.

                    std::cout.write(buf.data(), len);
                }
            }
            catch (std::exception& e)
            {
                std::cerr << e.what() << std::endl;
            }

            return 0;
        }

    主要流程如下:

    1. 通過tcp::socket類定義一個tcp client對象socket
    2. 通過connect函數連接服務器,打開socket連接。
    3. 通過read_some函數來讀數據

    另外,還可以通過write_some來寫數據,通過close來關閉socket連接(這里是通過釋放socket對象隱式釋放連接)。

    服務器

    服務器代碼如下:

        #include <ctime>
        #include <iostream>
        #include <string>
        #include <boost/asio.hpp>

        using namespace boost;
        using boost::asio::ip::tcp;

        int main()
        {
            try
            {
                asio::io_service io_service;
                tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3200));

                for (;;)
                {
                    tcp::socket socket(io_service);
                    acceptor.accept(socket);

                    time_t now = time(0);
                    std::string message = ctime(&now);

                    system::error_code ignored_error;
                    socket.write_some(asio::buffer(message), ignored_error);
                }
            }
            catch (std::exception& e)
            {
                std::cerr << e.what() << std::endl;
            }

            return 0;
        }

    主要流程如下:

    1. 通過tcp::acceptor類創建一個tcp server對象,并綁定端口(也可以不在構造器中自動綁定,而通過bind函數手動綁定)
    2. 通過accept函數獲取遠端連接
    3. 通過遠端連接的write_some函數將數據發往客戶端

    異步服務器

    前面的服務器是同步版本,在大并發的場景下一般需要用到異步socket。服務器的異步版本如下:

        #include <ctime>
        #include <iostream>
        #include <string>
        #include <memory>
        #include <functional>
        #include <boost/asio.hpp>

        using boost::asio::ip::tcp;
        using namespace std;

        void process_client(shared_ptr<tcp::socket> client)
        {
            time_t now = time(0);
            shared_ptr<string> message(new string(ctime(&now)));

            auto callback = [=](const boost::system::error_code& err ,size_t size)
            {
                if ((int)size == message->length())
                    cout << "write completed" << endl;
            };

            client->async_send(boost::asio::buffer(*message), callback);
        }

        typedef function<void (const boost::system::error_code&)> accept_callback;
        void start_accept(tcp::acceptor& server)
        {
            shared_ptr<tcp::socket> client(new tcp::socket(server.get_io_service()));
            accept_callback callback = [&server, client](const boost::system::error_code& error)
                {
                    if (!error)
                        process_client(client);

                    start_accept(server);
                };

            server.async_accept(*client, callback);
        }

        int main()
        {
            try
            {
                boost::asio::io_service io_service;
                tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3200));
                start_accept(acceptor);
                io_service.run();
            }
            catch (std::exception& e)
            {
                std::cerr << e.what() << std::endl;
            }
            return 0;
        }

    這個異步版本的邏輯倒不是很復雜,基本上和.net中傳統的異步socket相似,不過需要注意的是,由于c++中內存需要自己管理,而asio框架也沒有提供任何管理機制,因此需要注意async_accept、async_send等函數的參數生命周期,切記不能在里面傳入棧變量的引用。如果是堆變量,需要確保釋放,本例中我是通過share_ptr來實現的自動釋放。

    更多的示例請參看asio官方文檔

    FROM:http://www.cnblogs.com/TianFang/archive/2013/02/02/2890529.html

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全