標準ソケットを使用した次のコードがあります。
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))
、ブラウザ クライアントからのデータをソックス プロキシ経由で読み取ることができるが、上記の ProxySession::Start のバージョンでは、どのような状況でも HandleProxyRead が呼び出されないことです。
ここでデータを交換する非同期の方法は本当に必要ありません。それは、ここでこのソリューションを思いついたということだけです。また、ProxySession->start from code を呼び出した場所から、スリープを導入する必要がありました。そうしないと、これが実行されていたスレッド コンテキストがシャットダウンされていたからです。
*更新 2 *以下の私の更新の 1 つを参照してください。質問ブロックが大きくなりすぎています。