C++ Boost::Asio:异步读取的问题
我正在编写一个简单的ProxyServer,它分析包并将包发送到另一个服务器实例,例如: 客户端->MyProxy->SQLServer->C++ Boost::Asio:异步读取的问题,c++,boost-asio,C++,Boost Asio,我正在编写一个简单的ProxyServer,它分析包并将包发送到另一个服务器实例,例如: 客户端->MyProxy->SQLServer-> 客户端我怀疑发生的情况是,您的一个async\u read\u some调用正在返回“some”数据,但这还不足以让SQL server确信它已收到完整的请求。您的代码始终遵循从\u客户端读取\u->将\u发送到\u服务器->从\u服务器读取\u->将\u发送到\u客户端的路径。它不处理需要从\u客户端读取\u->发送到\u服务器->从\u客户端读取\u-
客户端我怀疑发生的情况是,您的一个async\u read\u some调用正在返回“some”数据,但这还不足以让SQL server确信它已收到完整的请求。您的代码始终遵循从\u客户端读取\u->将\u发送到\u服务器->从\u服务器读取\u->将\u发送到\u客户端的路径。它不处理需要从\u客户端读取\u->发送到\u服务器->从\u客户端读取\u->发送到\u服务器->从\u服务器读取\u->发送到\u客户端的情况
到目前为止,您编写的代码执行的操作与原始代码不同。具体来说,旧代码同时侦听两个套接字上的读取。幸运的是,因为您使用的是ASIO,所以不需要弄乱线程。只需在两个套接字上同时发出异步读取请求,并异步处理它们 为什么要将
recv()
和send()
调用与ASIO混合匹配?我认为您需要更改recv(2)的错误处理,以便它检查成功,然后假设失败,而不是假设唯一的返回代码是SOCKET\u error
@Sean我不认为@user在混合它们,使用send
和recv
的代码是一些旧的winsock代码。是的,Winsock代码只是一个旧项目,用来展示它以前是如何完成的,Boost代码是新项目,所以我不会混合使用这两个API调用。@Sam Miller:会话数据是Boost::array data+1我必须对async_read_some()做同样的事情。在实现某种请求处理器时,必须在handle_read()中提供一些处理,以将一个或多个读取合并成完整的请求。感谢您的回答,我将尝试检查是否有更多数据要从套接字读取,如果有,请在我的读取回调方法中处理。
#include "session.h"
#include <iostream>
using namespace std;
session::session(boost::asio::io_service& io_service)
: socket_(io_service)
, sqlsocket_(io_service)
, io_service_(io_service)
, resolver(io_service)
{
cout << "session::session()" << endl;
}
session::~session()
{
cout << "session::~session()" << endl;
cout << "closing session ..." << endl;
}
tcp::socket& session::socket()
{
return socket_;
}
void session::start()
{
cout << "session::start()" << endl;
cout << "starting session ..." << endl;
// connect to the sqlserver database
tcp::resolver::query query("192.168.1.50", "1317");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::endpoint endpoint = *endpoint_iterator;
sqlsocket_.async_connect(endpoint,
boost::bind(&session::handle_sqlserver_connect, this,
boost::asio::placeholders::error, ++endpoint_iterator));
// TODO: connect to the connector
}
void session::handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
cout << "session::handle_read()" << endl;
if (!error)
{
cout << "session::handle_read() (read: "
<< bytes_transferred << ")"
<< endl;
boost::asio::async_write(sqlsocket_,
boost::asio::buffer(data_, bytes_transferred),
boost::bind(&session::handle_sqlserver_write, this,
boost::asio::placeholders::error, bytes_transferred));
}
else
{
delete this;
}
}
void session::handle_sqlserver_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
cout << "session::handle_sqlserver_read()" << endl;
if (!error)
{
cout << "session::handle_sqlserver_read() (read: "
<< bytes_transferred << ")"
<< endl;
boost::asio::async_write(socket_,
boost::asio::buffer(data_, bytes_transferred),
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error, bytes_transferred));
}
else
{
delete this;
}
}
void session::handle_write(const boost::system::error_code& error,
size_t bytes_transferred)
{
static int count = 0;
cout << ++count << ". session::handle_write()" << endl;
if (!error)
{
cout << "session::handle_write() (read: "
<< bytes_transferred << ")"
<< endl;
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
delete this;
}
}
void session::handle_sqlserver_write(const boost::system::error_code& error,
size_t bytes_transferred)
{
cout << "session::handle_sqlserver_write()" << endl;
if (!error)
{
cout << "session::handle_sqlserver_write() (read: "
<< bytes_transferred << ")"
<< endl;
sqlsocket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_sqlserver_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
delete this;
}
}
void session::handle_sqlserver_connect(const boost::system::error_code& error,
tcp::resolver::iterator endpoint_iterator)
{
cout << "session::handle_sqlserver_connect()" << endl;
if (!error)
{
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else if (endpoint_iterator != tcp::resolver::iterator())
{
sqlsocket_.close();
tcp::endpoint endpoint = *endpoint_iterator;
sqlsocket_.async_connect(endpoint,
boost::bind(&session::handle_sqlserver_connect, this,
boost::asio::placeholders::error, ++endpoint_iterator));
}
}
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)listenatclient, (LPVOID)cs, 0, 0);
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)listenatserver, (LPVOID)cs, 0, 0);
void listenatclient(LPVOID connection)
{
connection_s* cs = (connection_s*)connection;
char inMessagecli[MSG_SIZE];
int rcount = 0;
...
do
{
memset(inMessagecli, 0, MSG_SIZE);
rcount = recv((SOCKET)cs->client, inMessagecli, MSG_SIZE, 0);
if (rcount != SOCKET_ERROR)
{
// analyze package
...
send((SOCKET)cs->server, inMessagecli, rcount, 0);
}
} while (rcount > 0);
}
void listenatserver(LPVOID connection)
{
connection_s* cs = (connection_s*)connection;
char inMessageserv[MSG_SIZE];
int rcount = 0;
do
{
memset(inMessageserv, 0, MSG_SIZE);
rcount = recv((SOCKET)cs->server, inMessageserv, MSG_SIZE, 0);
if (rcount != SOCKET_ERROR)
{
send((SOCKET)cs->client, inMessageserv, rcount, 0);
}
} while (rcount > 0);
}