boost asio - 编写等效的代码

Posted

技术标签:

【中文标题】boost asio - 编写等效的代码【英文标题】:boost asio - write equivalent piece of code 【发布时间】:2012-01-28 08:51:23 【问题描述】:

我有这段代码使用标准套接字:

void set_fds(int sock1, int sock2, fd_set *fds) 
    FD_ZERO (fds);
    FD_SET (sock1, fds); 
    FD_SET (sock2, fds); 


void do_proxy(int client, int conn, char *buffer) 
    fd_set readfds; 
    int result, nfds = max(client, conn)+1;
    set_fds(client, conn, &readfds);
    while((result = select(nfds, &readfds, 0, 0, 0)) > 0) 
        if (FD_ISSET (client, &readfds)) 
            int recvd = recv(client, buffer, 256, 0);
            if(recvd <= 0)
                return;
            send_sock(conn, buffer, recvd);
        
        if (FD_ISSET (conn, &readfds)) 
            int recvd = recv(conn, buffer, 256, 0);
            if(recvd <= 0)
                return;
            send_sock(client, buffer, recvd);
        
        set_fds(client, conn, &readfds);
    

我有套接字客户端和连接,我需要在它们之间“代理”流量(这是 socks5 服务器实现的一部分,您可能会看到 https://github.com/mfontanini/Programs-Scripts/blob/master/socks5/socks5.cpp)。如何在 asio 下实现这一点?

我必须指定在此之前两个套接字都在阻塞模式下运行。

尝试使用它但没有成功:

ProxySession::ProxySession(ba::io_service& ioservice, socket_ptr socket, socket_ptr clientSock): ioService_(ioService), socket_(socket), clientSock_(clientSock)




void ProxySession::Start()

    socket_->async_read_some(boost::asio::buffer(data_, 1),
        boost::bind(&ProxySession::HandleProxyRead, this,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred));    


void ProxySession::HandleProxyRead(const boost::system::error_code& error,
      size_t bytes_transferred)

    if (!error)
    
      boost::asio::async_write(*clientSock_,
          boost::asio::buffer(data_, bytes_transferred),
          boost::bind(&ProxySession::HandleProxyWrite, this,
            boost::asio::placeholders::error));
    
    else
    
      delete this;
    



void ProxySession::HandleProxyWrite(const boost::system::error_code& error)

   if (!error)
    
       socket_->async_read_some(boost::asio::buffer(data_, max_length),
        boost::bind(&ProxySession::HandleProxyRead, this,
          boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred));
    
    else
    
      delete this;
    

问题是,如果我这样做 ba::read(*socket_, ba::buffer(data_,256)),我可以通过 socks 代理读取来自浏览器客户端的数据,但在 ProxySession::Start 以上版本中,在任何情况下都不会调用 HandleProxyRead。

我真的不需要在这里交换数据的异步方式,只是我在这里采用了这个解决方案。同样从我调用 ProxySession->从代码开始,我需要引入睡眠,否则执行它的线程上下文将被关闭。

*更新 2 * 请看下面我的更新之一。问题块太大了。

【问题讨论】:

你试过什么?阅读 asio 文档,尝试转换您的代码。如果您在特定问题上被阻止,请询问。但不要指望人们会在这里为您进行转换。 @Mat 基本上直到现在我在这些套接字上使用了 asio::read 和 asio::write 。但是当尝试使用 aync_read/async_write 他们不再工作了。包含有问题的详细信息。 【参考方案1】:

这个问题可以通过使用异步写/读函数来解决,以便与呈现的代码有类似的东西。基本上使用 async_read_some()/async_write() - 或这些类别中的其他异步函数。此外,为了使异步处理正常工作,必须调用 boost::asio::io_service.run() 它将为异步处理调度完成处理程序。

【讨论】:

【参考方案2】:

我已经设法做到了。该解决方案解决了 2 个套接字的“数据交换”问题(根据 socks5 服务器代理必须发生),但计算量很大。有什么想法吗?

std::size_t readable = 0;

    boost::asio::socket_base::bytes_readable command1(true);
    boost::asio::socket_base::bytes_readable command2(true);


    try 
    
        while (1)
        
            socket_->io_control(command1);
            clientSock_->io_control(command2);

            if ((readable = command1.get()) > 0)
            
                transf = ba::read(*socket_, ba::buffer(data_,readable));
                ba::write(*clientSock_, ba::buffer(data_,transf));
                boost::this_thread::sleep(boost::posix_time::milliseconds(500));
            

            if ((readable = command2.get()) > 0)
            
                transf = ba::read(*clientSock_, ba::buffer(data_,readable));
                ba::write(*socket_, ba::buffer(data_,transf));
                boost::this_thread::sleep(boost::posix_time::milliseconds(500));
            
        
    
    catch (std::exception& ex)
    
        std::cerr << "Exception in thread while exchanging: " << ex.what() << "\n";
        return;
    

【讨论】:

以上是关于boost asio - 编写等效的代码的主要内容,如果未能解决你的问题,请参考以下文章

如何将 boost.Asio 与 MJPEG 一起使用?

C++ 线程与 boost asio

boost::asio::read() 永远阻塞

对同一链中的 boost::asio::yield 执行顺序感到困惑

boost::asio::io_service类

试图了解 Boost.Asio 自定义服务实现