• <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>

            應用場景是這樣的:

            客戶端和服務器在不同的網段內,它們之間不能直接通過TCP連接,但是有一臺機器(暫時稱為轉發器)有雙網卡,兩塊網卡分別在客戶端和服務器端的網段內,這樣轉發器就能分別和客戶端即服務器建立連接,并來回傳輸數據。

            設計思路是這樣的:

            當客戶端連接到轉發器后,轉發器馬上建立一條到服務器之間的連接,與服務器端的連接建立后,就同時異步地從客戶端和服務器端接收數據到兩個緩沖區 中,一旦任何一方有數據接收,就通過另外一條連接將數據發送到另一方,發送完畢后又開始新一輪的數據接收。如果在接收數據的過程中有任何一方出現錯誤,就 將取消另外一條連接的異步調用,這樣整個連接就會關閉。

            其中用到了Boost庫的以下特性:

            1.Asio的異步IO調用

            2.多線程

            3.share_ptr的自動指針管理

            遺留的一些問題:

            由于采用了多線程,為了保險起見,我將每個回調函數都用strand包裹起來,在各回調函數沒有使用共享資源的情況下并不必要,因此在這方面可以優化下
             1 /*
             2  * =====================================================================================
             3  *
             4  * Filename: xproxy_main.cpp
             5  *
             6  * Description:
             7  *
             8  * Version: 1.0
             9  * Created: 2009年11月26 日 15時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時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時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時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時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寫的多線程TCP轉發代理服務器  回復  更多評論   

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

            # re: 使用Boost.Asio寫的多線程TCP轉發代理服務器  回復  更多評論   

            2010-03-06 12:24 by David Fang
            嘿嘿,這個是安全項目的內幕,為了保護背后的網絡。

            # re: 使用Boost.Asio寫的多線程TCP轉發代理服務器  回復  更多評論   

            2010-03-07 11:22 by ziding
            若A發送一段數據到proxy之后,連接斷掉了,proxy是不是否會把之前收到的內容發給后面的服務器b?要是不發,是不是不太合適?

            # re: 使用Boost.Asio寫的多線程TCP轉發代理服務器  回復  更多評論   

            2010-03-07 22:09 by David Fang
            A(我理解是客戶端)發送的數據被xproxy_connection收到后,會調用handle_login_clt_sock_read,它將客戶端發來的數據到服務器,這時如果A和代理間的連接掉了不影響數據發到服務器。當之前從客戶端收到的數據從代理發到服務器完畢后,handle_ana_srv_sock_write被調用,代理又開始從客戶端接收數據,這才發現客戶端關閉連接了,異步調用的處理函數handle_login_clt_sock_read會得到一個錯誤,然后就撤銷與服務器連接的socket的所有請求,而本身和客戶端連接的socket有沒有新的調用,因此整個連接會被釋放,應該還算比較合理吧。

            # re: 使用Boost.Asio寫的多線程TCP轉發代理服務器  回復  更多評論   

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

            # re: 使用Boost.Asio寫的多線程TCP轉發代理服務器[未登錄]  回復  更多評論   

            2013-09-23 17:52 by a
            理論上只能最大代理65535路TCP,因為你在與被代理服務器通訊時是需要用端口的。我說的大家怎么看?

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

            Copyright © David Fang

            久久中文字幕人妻丝袜| 久久噜噜久久久精品66| 久久精品国产99国产精品| 亚洲日韩中文无码久久| 亚洲国产日韩欧美综合久久| 久久99久久99小草精品免视看| 亚洲国产精品高清久久久| 久久精品日日躁夜夜躁欧美| 久久综合亚洲色一区二区三区| 婷婷久久综合| 一本一本久久a久久精品综合麻豆| 久久久久国色AV免费看图片| 久久青青草原精品国产软件 | 久久精品人人做人人爽97| 亚洲AV无码久久| 久久夜色精品国产噜噜亚洲AV| 亚洲国产精品18久久久久久| 久久久久久久97| 欧美久久综合性欧美| 精品久久久久久无码国产| 无码任你躁久久久久久久| 久久久久亚洲AV无码去区首| 久久综合久久鬼色| 午夜精品久久久久久99热| 99久久精品国产高清一区二区 | 久久国产亚洲高清观看| 狠狠色丁香久久婷婷综合五月 | 精品久久久久久无码人妻蜜桃| 免费精品久久久久久中文字幕| 久久99热这里只有精品国产| 久久婷婷五月综合色奶水99啪 | 色婷婷综合久久久久中文 | 国产亚洲色婷婷久久99精品91| 久久天天躁狠狠躁夜夜2020| 亚洲欧美伊人久久综合一区二区| 好久久免费视频高清| 久久久久亚洲av毛片大| 国内精品久久久久久久97牛牛| 国产午夜精品理论片久久| 久久亚洲精品无码AV红樱桃| 精品久久久久久国产牛牛app|