• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            應(yīng)用場(chǎng)景是這樣的:

            客戶端和服務(wù)器在不同的網(wǎng)段內(nèi),它們之間不能直接通過(guò)TCP連接,但是有一臺(tái)機(jī)器(暫時(shí)稱為轉(zhuǎn)發(fā)器)有雙網(wǎng)卡,兩塊網(wǎng)卡分別在客戶端和服務(wù)器端的網(wǎng)段內(nèi),這樣轉(zhuǎn)發(fā)器就能分別和客戶端即服務(wù)器建立連接,并來(lái)回傳輸數(shù)據(jù)。

            設(shè)計(jì)思路是這樣的:

            當(dāng)客戶端連接到轉(zhuǎn)發(fā)器后,轉(zhuǎn)發(fā)器馬上建立一條到服務(wù)器之間的連接,與服務(wù)器端的連接建立后,就同時(shí)異步地從客戶端和服務(wù)器端接收數(shù)據(jù)到兩個(gè)緩沖區(qū) 中,一旦任何一方有數(shù)據(jù)接收,就通過(guò)另外一條連接將數(shù)據(jù)發(fā)送到另一方,發(fā)送完畢后又開(kāi)始新一輪的數(shù)據(jù)接收。如果在接收數(shù)據(jù)的過(guò)程中有任何一方出現(xiàn)錯(cuò)誤,就 將取消另外一條連接的異步調(diào)用,這樣整個(gè)連接就會(huì)關(guān)閉。

            其中用到了Boost庫(kù)的以下特性:

            1.Asio的異步IO調(diào)用

            2.多線程

            3.share_ptr的自動(dòng)指針管理

            遺留的一些問(wèn)題:

            由于采用了多線程,為了保險(xiǎn)起見(jiàn),我將每個(gè)回調(diào)函數(shù)都用strand包裹起來(lái),在各回調(diào)函數(shù)沒(méi)有使用共享資源的情況下并不必要,因此在這方面可以優(yōu)化下
             1 /*
             2  * =====================================================================================
             3  *
             4  * Filename: xproxy_main.cpp
             5  *
             6  * Description:
             7  *
             8  * Version: 1.0
             9  * Created: 2009年11月26 日 15時(shí)10分29秒
            10  * Revision: none
            11  * Compiler: gcc
            12  *
            13  * Author: David Fang (A free programmer), qi_fd@163.com
            14  * Company: nocompany
            15  *
            16  * =====================================================================================
            17  */
            18 
            19 #include <iostream>
            20 #include <string>
            21 #include <boost/asio.hpp>
            22 #include "xproxy_server.hpp"
            23 
            24 int main(int argc, char* argv[])
            25 {
            26     try
            27     {
            28         if(5 != argc)
            29         {
            30             std::cerr<<"Usage: xproxy <local port> <server ip> <server_port> <[thread size>\n";
            31             std::cerr<<"local port: local port used to accept login client\n";
            32             std::cerr<<"server ip: analysing server address, ip string in decimal dot format\n";
            33             std::cerr<<"server port: analysing server port, an unsigned short value\n";
            34             std::cerr<<"thread size: number of threads to running xproxy server\n";
            35             return 1;
            36         }
            37         xproxy_server srv(atoi(argv[1]), argv[2], atoi(argv[3]), atoi(argv[4]));
            38 
            39         srv.run();
            40     }
            41     catch(std::exception& e)
            42     {
            43         std::cerr<<"exception: "<<e.what()<<"\n";
            44     }
            45 
            46     return 0;
            47 }
             1 /*
             2  * =====================================================================================
             3  *
             4  * Filename: xproxy_server.hpp
             5  *
             6  * Description:
             7  *
             8  * Version: 1.0
             9  * Created: 2009年11月26 日 15時(shí)12分01秒
            10  * Revision: none
            11  * Compiler: gcc
            12  *
            13  * Author: David Fang (A free programmer), qi_fd@163.com
            14  * Company: nocompany
            15  *
            16  * =====================================================================================
            17  */
            18 #ifndef XPROXY_SERVER_HPP
            19 #define XPROXY_SERVER_HPP
            20 
            21 #include <string>
            22 
            23 #include <boost/asio.hpp>
            24 #include <boost/noncopyable.hpp>
            25 #include <boost/shared_ptr.hpp>
            26 #include "xproxy_connection.hpp"
            27 
            28 using boost::asio::ip::tcp;
            29 
            30 class xproxy_server:private boost::noncopyable
            31 {
            32 public:
            33 
            34     //construction of xproxy_server, which takes the destination machine(analysing server)'s
            35 
            36     //address and port(ipv4) as arguments
            37 
            38     explicit xproxy_server(unsigned short local_port, const std::string& ana_address, unsigned short ana_port,
            39             std::size_t thread_pool_size = 1);
            40     
            41     //Run the server's io_service loop
            42 
            43     void run();
            44 
            45     //Stop the server
            46 
            47     void stop();
            48 private:
            49     //Handle the completion of an asynchronous accept from the login client
            50 
            51     void handle_accept(const boost::system::error_code& e);
            52 
            53     //The number of threads that will call io_service::run()
            54 
            55     std::size_t thread_pool_size_;
            56 
            57     //The io_service used to perform asynchronous operations.
            58 
            59     boost::asio::io_service io_service_;
            60 
            61     //Acceptor used to listen for incoming proxy connectins
            62 
            63     boost::asio::ip::tcp::acceptor acceptor_;
            64 
            65     //Local endpoint corresponding to the login client
            66 
            67     tcp::endpoint local_endpoint_;
            68 
            69     //The endpoint to analysing server
            70 
            71     tcp::endpoint analysing_server_endpoint_;
            72 
            73     //The next connectin to be accepted.
            74 
            75     xproxy_connection_ptr new_connection_;
            76 };
            77 
            78 #endif
             1 /*
             2  * =====================================================================================
             3  *
             4  * Filename: xproxy_server.cpp
             5  *
             6  * Description:
             7  *
             8  * Version: 1.0
             9  * Created: 2009年11月26 日 15時(shí)12分07秒
            10  * Revision: none
            11  * Compiler: gcc
            12  *
            13  * Author: David Fang (A free programmer), qi_fd@163.com
            14  * Company: nocompany
            15  *
            16  * =====================================================================================
            17  */
            18 
            19 #include "xproxy_server.hpp"
            20 #include <boost/thread.hpp>
            21 #include <boost/bind.hpp>
            22 #include <boost/shared_ptr.hpp>
            23 #include <vector>
            24 
            25 xproxy_server::xproxy_server(unsigned short local_port,
            26         const std::string& ana_address,
            27         unsigned short ana_port,
            28         std::size_t thread_pool_size)
            29     :thread_pool_size_(thread_pool_size),
            30     acceptor_(io_service_),
            31     local_endpoint_(tcp::v4(), local_port),
            32     analysing_server_endpoint_(boost::asio::ip::address::from_string(ana_address), ana_port),
            33     new_connection_(new xproxy_connection(io_service_, analysing_server_endpoint_))
            34 {
            35     acceptor_.open(local_endpoint_.protocol());
            36     acceptor_.set_option(tcp::acceptor::reuse_address(true));
            37     acceptor_.bind(local_endpoint_);
            38     acceptor_.listen();
            39     acceptor_.async_accept(new_connection_->login_clt_sock(),
            40             boost::bind(&xproxy_server::handle_accept, this,
            41                 boost::asio::placeholders::error));
            42 }
            43 
            44 void xproxy_server::run()
            45 {
            46     std::vector<boost::shared_ptr<boost::thread> > threads;
            47     for(std::size_t i = 0; i < thread_pool_size_; ++i)
            48     {
            49         boost::shared_ptr<boost::thread> thread(new boost::thread(
            50             boost::bind(&boost::asio::io_service::run, &io_service_)));
            51         threads.push_back(thread);
            52     }
            53 
            54     for(std::size_t i = 0; i < threads.size(); ++i)
            55     {
            56         threads[i]->join();
            57     }
            58 }
            59 
            60 void xproxy_server::stop()
            61 {
            62     io_service_.stop();
            63 }
            64 
            65 void xproxy_server::handle_accept(const boost::system::error_code& e)
            66 {
            67     if(!e)
            68     {
            69         new_connection_->start();
            70         new_connection_.reset(new xproxy_connection(io_service_,
            71             analysing_server_endpoint_));
            72 
            73         acceptor_.async_accept(new_connection_->login_clt_sock(),
            74             boost::bind(&xproxy_server::handle_accept, this,
            75                 boost::asio::placeholders::error));
            76     }
            77 }
             1 /*
             2  * =====================================================================================
             3  *
             4  * Filename: xproxy_connection.hpp
             5  *
             6  * Description:
             7  *
             8  * Version: 1.0
             9  * Created: 2009年11月26 日 15時(shí)11分04秒
            10  * Revision: none
            11  * Compiler: gcc
            12  *
            13  * Author: David Fang (A free programmer), qi_fd@163.com
            14  * Company: nocompany
            15  *
            16  * =====================================================================================
            17  */
            18 #ifndef XPROXY_CONNECTION_HPP
            19 #define XPROXY_CONNECTION_HPP
            20 
            21 #include <boost/asio.hpp>
            22 #include <boost/array.hpp>
            23 #include <boost/noncopyable.hpp>
            24 #include <boost/shared_ptr.hpp>
            25 #include <boost/enable_shared_from_this.hpp>
            26 
            27 using boost::asio::ip::tcp;
            28 
            29 class xproxy_connection:public boost::enable_shared_from_this<xproxy_connection>,
            30     private boost::noncopyable
            31 {
            32 public:
            33     //Contruct a connection with the given io_service, the analysing server address and port
            34 
            35     explicit xproxy_connection(boost::asio::io_service& io_service,
            36             tcp::endpoint& ana_endpoint);
            37 
            38     ~xproxy_connection();
            39 
            40     //Start the asyncronous connection to analysing server
            41 
            42     void start();
            43 
            44     tcp::socket& login_clt_sock();
            45 
            46 private:
            47     //Handle completion of connection to analysing server
            48 
            49     void handle_connect_to_ana_server(const boost::system::error_code& e);
            50 
            51     //Handle completion of login client socket read
            52 
            53     void handle_login_clt_sock_read(const boost::system::error_code& e,
            54             std::size_t bytes_transferred);
            55 
            56     //Handle completion of analysing server socket write
            57 
            58     void handle_ana_srv_sock_write(const boost::system::error_code& e);
            59 
            60     //Handle completion of analysing server socket read
            61 
            62     void handle_ana_srv_sock_read(const boost::system::error_code& e,
            63             std::size_t bytes_transferred);
            64 
            65     //Handle completion of login client socket write
            66 
            67     void handle_login_clt_sock_write(const boost::system::error_code& e);
            68 
            69     //Strand to ensure the connection's handles are not called concurrently
            70 
            71     boost::asio::io_service::strand strand_;
            72 
            73     //analysing server endpoint
            74 
            75     tcp::endpoint ana_endpoint_;
            76 
            77     //socket to the flex login client
            78 
            79     tcp::socket login_clt_sock_;
            80 
            81     //socket to analysing server
            82 
            83     tcp::socket ana_srv_sock_;
            84 
            85     //buffer used to recieve data from the login client
            86 
            87     boost::array<char1024> clt_buffer_;
            88     
            89     //buffer used to recieve data from the analysing server
            90 
            91     boost::array<char1024> srv_buffer_;
            92 };
            93 
            94 typedef boost::shared_ptr<xproxy_connection> xproxy_connection_ptr;
            95 
            96 #endif
              1 /*
              2  * =====================================================================================
              3  *
              4  * Filename: xproxy_connection.cpp
              5  *
              6  * Description:
              7  *
              8  * Version: 1.0
              9  * Created: 2009年11月26 日 15時(shí)12分33秒
             10  * Revision: none
             11  * Compiler: gcc
             12  *
             13  * Author: David Fang (A free programmer), qi_fd@163.com
             14  * Company: nocompany
             15  *
             16  * =====================================================================================
             17  */
             18 
             19 #include "xproxy_connection.hpp"
             20 #include <vector>
             21 #include <iostream>
             22 #include <boost/bind.hpp>
             23 
             24 xproxy_connection::xproxy_connection(boost::asio::io_service& io_service,
             25     tcp::endpoint& ana_endpoint)
             26     :strand_(io_service),
             27     ana_endpoint_(ana_endpoint),
             28     login_clt_sock_(io_service),
             29     ana_srv_sock_(io_service)
             30 {
             31     std::cout<<"new connection construct\n";
             32 }
             33 
             34 xproxy_connection::~xproxy_connection()
             35 {
             36     std::cout<<"connection destruct\n";
             37 }
             38 
             39 tcp::socket& xproxy_connection::login_clt_sock()
             40 {
             41     return login_clt_sock_;
             42 }
             43         
             44 void xproxy_connection::start()
             45 {
             46     std::cout<<"connection start to connect to analysing server\n";
             47     ana_srv_sock_.async_connect(ana_endpoint_,
             48         strand_.wrap(boost::bind(&xproxy_connection::handle_connect_to_ana_server,
             49             shared_from_this(), boost::asio::placeholders::error)));
             50 }
             51 
             52 void xproxy_connection::handle_connect_to_ana_server(const boost::system::error_code& e)
             53 {
             54     if(!e)
             55     {
             56         std::cout<<"connect to analysing server succeed,"
             57             <<"now start to receive data from both sides\n";
             58 
             59         login_clt_sock_.async_read_some(boost::asio::buffer(clt_buffer_),
             60                 strand_.wrap(
             61                     boost::bind(&xproxy_connection::handle_login_clt_sock_read,
             62                         shared_from_this(), boost::asio::placeholders::error,
             63                         boost::asio::placeholders::bytes_transferred)));
             64 
             65         ana_srv_sock_.async_read_some(boost::asio::buffer(srv_buffer_),
             66                 strand_.wrap(
             67                     boost::bind(&xproxy_connection::handle_ana_srv_sock_read,
             68                         shared_from_this(), boost::asio::placeholders::error,
             69                         boost::asio::placeholders::bytes_transferred)));
             70 
             71     }
             72 }
             73 
             74 void xproxy_connection::handle_login_clt_sock_read
             75     (const boost::system::error_code& e, std::size_t bytes_transferred)
             76 {
             77     if(!e)
             78     {
             79         std::cout<<"data read from login client:\n";
             80         std::cout.write(clt_buffer_.data(), bytes_transferred);
             81         std::cout<<"\nnow send it to analysing server\n";
             82         boost::asio::async_write(ana_srv_sock_,
             83                 boost::asio::buffer(clt_buffer_.data(), bytes_transferred),
             84                 strand_.wrap(boost::bind(
             85                         &xproxy_connection::handle_ana_srv_sock_write,
             86                         shared_from_this(), boost::asio::placeholders::error)));
             87     }
             88     else
             89     {
             90         std::cout<<"read data from login client error, "
             91             <<"now need to shutdown this connection\n";
             92         ana_srv_sock_.cancel();
             93     }
             94 }
             95 
             96 void xproxy_connection::handle_ana_srv_sock_write(const boost::system::error_code& e)
             97 {
             98     if(!e)
             99     {
            100         std::cout<<"data send to analysing server complete, "
            101             <<"now start to receive data from login client again\n";
            102         login_clt_sock_.async_read_some(boost::asio::buffer(clt_buffer_),
            103                 strand_.wrap(
            104                     boost::bind(&xproxy_connection::handle_login_clt_sock_read,
            105                         shared_from_this(), boost::asio::placeholders::error,
            106                         boost::asio::placeholders::bytes_transferred)));
            107     }
            108 }
            109 
            110 void xproxy_connection::handle_ana_srv_sock_read(
            111         const boost::system::error_code& e,
            112         std::size_t bytes_transferred)
            113 {
            114     if(!e)
            115     {
            116         std::cout<<"data read from analysing server:\n";
            117         std::cout.write(srv_buffer_.data(), bytes_transferred);
            118         std::cout<<"\nnow send it to login client\n";
            119         boost::asio::async_write(login_clt_sock_,
            120                 boost::asio::buffer(srv_buffer_.data(), bytes_transferred),
            121                 strand_.wrap(
            122                     boost::bind(&xproxy_connection::handle_login_clt_sock_write,
            123                         shared_from_this(), boost::asio::placeholders::error)));
            124     }
            125     else
            126     {
            127         std::cout<<"read data from analysing server error, "
            128             <<"now need to shutdown this connection\n";
            129         login_clt_sock_.cancel();
            130     }
            131 }
            132 
            133 void xproxy_connection::handle_login_clt_sock_write(const boost::system::error_code& e)
            134 {
            135     if(!e)
            136     {
            137         std::cout<<"data send to login client complete, "
            138             <<"now start to receive data from analysing server again\n";
            139         ana_srv_sock_.async_read_some(boost::asio::buffer(srv_buffer_),
            140                 strand_.wrap(
            141                     boost::bind(&xproxy_connection::handle_ana_srv_sock_read,
            142                         shared_from_this(), boost::asio::placeholders::error,
            143                         boost::asio::placeholders::bytes_transferred)));
            144     }
            145 }
             1 BOOST_INC=/home/done/dev_lib/boost_1_38_0/
             2 BOOST_LIB=/home/done/dev_lib/boostlibs/
             3 LIB_THREAD=$(BOOST_LIB)libboost_thread-gcc42-mt-s-1_38.a
             4 LIB_SYSTEM=$(BOOST_LIB)libboost_system-gcc42-mt-s-1_38.a
             5 SYS_INC=/usr/include/
             6 CPP_INC=/usr/include/c++/4.2/
             7 default:xproxy_main.o xproxy_server.o xproxy_connection.o
             8     g++ -o xproxy xproxy_main.o xproxy_server.o xproxy_connection.o $(LIB_THREAD) $(LIB_SYSTEM) -lpthread
             9 xproxy_main.o:xproxy_main.cpp xproxy_server.hpp
            10     g++ --I$(SYS_INC) -I$(BOOST_INC) -I$(CPP_INC) xproxy_main.cpp
            11 xproxy_server.o:xproxy_server.cpp xproxy_connection.hpp
            12     g++ --I$(SYS_INC) -I$(BOOST_INC) -I$(CPP_INC) xproxy_server.cpp
            13 xproxy_connection.o:xproxy_connection.cpp xproxy_connection.hpp
            14     g++ --I$(SYS_INC) -I$(BOOST_INC) -I$(CPP_INC) xproxy_connection.cpp
            15 clean:
            16     rm *.o xproxy 2>/dev/null

            Feedback

            # re: 使用Boost.Asio寫(xiě)的多線程TCP轉(zhuǎn)發(fā)代理服務(wù)器  回復(fù)  更多評(píng)論   

            2010-03-06 10:12 by zuhd
            奇怪為什么有這樣的需求?為什么不用udp,udp可以穿越NAT

            # re: 使用Boost.Asio寫(xiě)的多線程TCP轉(zhuǎn)發(fā)代理服務(wù)器  回復(fù)  更多評(píng)論   

            2010-03-06 12:24 by David Fang
            嘿嘿,這個(gè)是安全項(xiàng)目的內(nèi)幕,為了保護(hù)背后的網(wǎng)絡(luò)。

            # re: 使用Boost.Asio寫(xiě)的多線程TCP轉(zhuǎn)發(fā)代理服務(wù)器  回復(fù)  更多評(píng)論   

            2010-03-07 11:22 by ziding
            若A發(fā)送一段數(shù)據(jù)到proxy之后,連接斷掉了,proxy是不是否會(huì)把之前收到的內(nèi)容發(fā)給后面的服務(wù)器b?要是不發(fā),是不是不太合適?

            # re: 使用Boost.Asio寫(xiě)的多線程TCP轉(zhuǎn)發(fā)代理服務(wù)器  回復(fù)  更多評(píng)論   

            2010-03-07 22:09 by David Fang
            A(我理解是客戶端)發(fā)送的數(shù)據(jù)被xproxy_connection收到后,會(huì)調(diào)用handle_login_clt_sock_read,它將客戶端發(fā)來(lái)的數(shù)據(jù)到服務(wù)器,這時(shí)如果A和代理間的連接掉了不影響數(shù)據(jù)發(fā)到服務(wù)器。當(dāng)之前從客戶端收到的數(shù)據(jù)從代理發(fā)到服務(wù)器完畢后,handle_ana_srv_sock_write被調(diào)用,代理又開(kāi)始從客戶端接收數(shù)據(jù),這才發(fā)現(xiàn)客戶端關(guān)閉連接了,異步調(diào)用的處理函數(shù)handle_login_clt_sock_read會(huì)得到一個(gè)錯(cuò)誤,然后就撤銷與服務(wù)器連接的socket的所有請(qǐng)求,而本身和客戶端連接的socket有沒(méi)有新的調(diào)用,因此整個(gè)連接會(huì)被釋放,應(yīng)該還算比較合理吧。

            # re: 使用Boost.Asio寫(xiě)的多線程TCP轉(zhuǎn)發(fā)代理服務(wù)器  回復(fù)  更多評(píng)論   

            2011-09-30 21:52 by AQ
            貌似我也做了個(gè)類似的東西,BOOST的效率還是非常OK的,不過(guò)還是直接做個(gè)代理比較高效點(diǎn)

            # re: 使用Boost.Asio寫(xiě)的多線程TCP轉(zhuǎn)發(fā)代理服務(wù)器[未登錄](méi)  回復(fù)  更多評(píng)論   

            2013-09-23 17:52 by a
            理論上只能最大代理65535路TCP,因?yàn)槟阍谂c被代理服務(wù)器通訊時(shí)是需要用端口的。我說(shuō)的大家怎么看?

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            posts - 9, comments - 13, trackbacks - 0, articles - 0

            Copyright © David Fang

            欧美黑人激情性久久| 漂亮人妻被中出中文字幕久久 | 久久综合中文字幕| 香蕉99久久国产综合精品宅男自| 亚洲AV日韩精品久久久久久久| 99久久国产综合精品五月天喷水 | 亚洲国产精品久久久久婷婷老年| 日日狠狠久久偷偷色综合96蜜桃 | 精品久久久久久亚洲精品| 亚洲欧美国产精品专区久久| 99久久777色| 无码日韩人妻精品久久蜜桃| 亚洲欧美成人久久综合中文网| 国产免费久久久久久无码| 久久精品水蜜桃av综合天堂 | 国产毛片久久久久久国产毛片| 91精品国产综合久久久久久| 亚洲愉拍99热成人精品热久久| 亚洲精品国精品久久99热| 久久精品国产精品亚洲艾草网美妙| 国内精品久久久久久野外| 伊人久久大香线蕉综合影院首页| 久久性生大片免费观看性| 久久99精品久久久久久野外| 亚洲国产精品婷婷久久| 久久99国产精品一区二区| 91精品国产高清久久久久久io| 亚洲午夜无码久久久久| 久久人做人爽一区二区三区| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 久久久久亚洲av成人网人人软件| 久久人妻少妇嫩草AV蜜桃| 国内精品伊人久久久久影院对白| 热久久国产精品| 日本久久久精品中文字幕| 日本久久久久久中文字幕| 日韩精品国产自在久久现线拍| 久久久久免费精品国产| 久久久精品免费国产四虎| 91精品国产91久久久久久蜜臀| 99久久www免费人成精品|