boost-asio——编写等效的代码

boost asio - write equivalent piece of code

本文关键字:代码 boost-asio      更新时间:2023-10-16

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

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);
    }

我有socket-client和conn,我需要在它们之间"代理"流量(这是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。

我真的不需要一种异步的数据交换方式;It’我只是想出了这个解决方案。此外,从我调用ProxySession->的代码开始,我需要引入睡眠,因为否则执行该操作的线程上下文将被关闭。

*更新2*请参阅下面的一个更新。问题块太大了。

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

我已经设法做到了。此解决方案解决了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;
    }