且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使在C代理服务器++使用Boost

更新时间:2022-06-27 05:54:29

嗯,这里是一个有些功能例子让你开始。它把两个连接之间。请注意,这个简单的例子不会为一个Web浏览器的工作,作为客户端会尝试多个连接,而这个例子只是监听之一。以此为一个(很简单)的基础上,你应该能够取得一些进展。

Well, here's a somewhat functional example to get you started. It forwards between two connections. Note that this simple example won't work for a web browser, as the client will attempt to make several connections, and this example only listens on one. Using this as a (very simple) base, you should be able to make some progress.

有趣的东西发生在 handle_read ,这是接收数据时执行回调。此功能转发插槽之间的数据。请注意,当我们最初称它的订单,我们在反向传递的插座(本地和远程连接 read_from write_to )。

The interesting stuff happens in handle_read, which is the callback that is executed when data is received. This function forwards the data between sockets. Notice that when we originally called it for the "local" and "remote" connections that the order we passed the sockets in is reversed (read_from and write_to).

#include <iostream>
using namespace std;

#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

boost::asio::io_service& io_service()
{
   static boost::asio::io_service svc;
   return svc;
}

char local_data[1024] = {0};
char remote_data[1024] = {0};

void handle_read(
   boost::asio::ip::tcp::socket& read_from,
   boost::asio::ip::tcp::socket& write_to,
   char* read_buffer,
   size_t bytes,
   const boost::system::error_code& e)
{
   // this function is called whenever data is received

   // for debugging purposes, show the data in the console window
   // or write to file, or whatever...
   std::string data(read_buffer, read_buffer + bytes);    
   std::cout << data << "\n";

   // forward the received data on to "the other side"    
   write_to.send(
      boost::asio::buffer(read_buffer, bytes));

   // read more data from "this side"
   read_from.async_read_some(
      boost::asio::buffer(read_buffer, 1024),
      boost::bind(handle_read, boost::ref(read_from), boost::ref(write_to), read_buffer, boost::asio::placeholders::bytes_transferred, boost::asio::placeholders::error));
}

int main(int argc, char** argv)
{
   if(argc == 5)
   {
      boost::asio::io_service::work w(io_service());

      boost::thread t(boost::bind(&boost::asio::io_service::run, (&io_service())));

      // extract the connection information from the command line
      boost::asio::ip::address local_address = boost::asio::ip::address::from_string(argv[1]);
      uint16_t local_port = boost::lexical_cast<uint16_t>(argv[2]);
      boost::asio::ip::address remote_address = boost::asio::ip::address::from_string(argv[3]);
      uint16_t remote_port = boost::lexical_cast<uint16_t>(argv[4]);

      boost::asio::ip::tcp::endpoint local_ep(local_address, local_port);
      boost::asio::ip::tcp::endpoint remote_ep(remote_address, remote_port);

      // start listening on the "local" socket -- note this does not
      // have to be local, you could in theory forward through a remote device
      // it's called "local" in the logical sense    
      boost::asio::ip::tcp::acceptor listen(io_service(), local_ep);
      boost::asio::ip::tcp::socket local_socket(io_service());
      listen.accept(local_socket);

      // open the remote connection
      boost::asio::ip::tcp::socket remote_socket(io_service());
      remote_socket.open(remote_ep.protocol());
      remote_socket.connect(remote_ep);

      // start listening for data on the "local" connection
      local_socket.async_receive(
         boost::asio::buffer(local_data, 1024),
         boost::bind(handle_read, boost::ref(local_socket), boost::ref(remote_socket), local_data, boost::asio::placeholders::bytes_transferred, boost::asio::placeholders::error));

      // also listen for data on the "remote" connection
      remote_socket.async_receive(
         boost::asio::buffer(remote_data, 1024),
         boost::bind(handle_read, boost::ref(remote_socket), boost::ref(local_socket), remote_data, boost::asio::placeholders::bytes_transferred, boost::asio::placeholders::error));

      t.join();
   }
   else
   {
      cout << "proxy <local ip> <port> <remote ip> <port>\n";
   }

   return 0;
}