我有使用标准套接字的这段代码:
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);
}
我有套接字客户端和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。 / p>
我真的不需要在这里交换数据的异步方式,它只是我在这里得到了这个解决方案。同样从我调用ProxySession->从代码开始我需要引入一个sleep,因为否则执行它的线程上下文正在关闭。
* 更新2 * 请参阅下面的一条更新。问题块太大了。
答案 0 :(得分:1)
问题可以通过使用异步写/读函数来解决,以便与呈现的代码类似。基本上使用async_read_some()/ async_write() - 或这些类别中的其他异步函数。另外,为了使异步处理工作,必须调用boost :: asio :: io_service.run(),它将为异步处理调度完成处理程序。
答案 1 :(得分:0)
我设法得到了这个。这个解决方案解决了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;
}