los*_*iuk 1 c++ boost boost-asio
我是boost :: asio的新手,所以我的问题可能是愚蠢的 - 抱歉,如果是这样的话.我正在使用keepalive编写异步服务器应用程序(可以在单个连接上发送多个请求).
连接处理程序很简单:
在循环中:
使用socket-> async_read_some(buffer,handler)调度读取请求
来自处理程序计划使用async_write写入响应.
我面临的问题是当 传递给async_read_some的处理程序被io_service线程调用时,缓冲区实际上可能包含的数据多于单个请求(例如客户端发送的下一个请求的一部分).
我不想(并且不能,如果它只是请求的一部分)此时处理剩余的字节.处理完之前的请求后我想这样做.
如果我有可能将不必要的重新映射数据重新插入套接字,那么很容易解决这个问题.所以它在下一次async_read_some调用时处理.
boost :: asio中是否存在这样的可能性,或者我是否必须将剩余的数据存储在一边,并使用额外的代码自行处理.
我认为你要找的是asio :: streambuf.
基本上,您可以检查您的种子streambuf作为char*,尽可能多地阅读,然后通知实际处理了多少consume(amount).
工作代码示例将HTTP标头解析为客户端:
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <string>
namespace asio = boost::asio;
std::string LINE_TERMINATION = "\r\n";
class Connection {
asio::streambuf _buf;
asio::ip::tcp::socket _socket;
public:
Connection(asio::io_service& ioSvc, asio::ip::tcp::endpoint server)
: _socket(ioSvc)
{
_socket.connect(server);
_socket.send(boost::asio::buffer("GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"));
readMore();
}
void readMore() {
// Allocate 13 bytes space on the end of the buffer. Evil prime number to prove algorithm works.
asio::streambuf::mutable_buffers_type buf = _buf.prepare(13);
// Perform read
_socket.async_read_some(buf, boost::bind(
&Connection::onRead, this,
asio::placeholders::bytes_transferred, asio::placeholders::error
));
}
void onRead(size_t read, const boost::system::error_code& ec) {
if ((!ec) && (read > 0)) {
// Mark to buffer how much was actually read
_buf.commit(read);
// Use some ugly parsing to extract whole lines.
const char* data_ = boost::asio::buffer_cast<const char*>(_buf.data());
std::string data(data_, _buf.size());
size_t start = 0;
size_t end = data.find(LINE_TERMINATION, start);
while (end < data.size()) {
std::cout << "LINE:" << data.substr(start, end-start) << std::endl;
start = end + LINE_TERMINATION.size();
end = data.find(LINE_TERMINATION, start);
}
_buf.consume(start);
// Wait for next data
readMore();
}
}
};
int main(int, char**) {
asio::io_service ioSvc;
// Setup a connection and run
asio::ip::address localhost = asio::ip::address::from_string("127.0.0.1");
Connection c(ioSvc, asio::ip::tcp::endpoint(localhost, 80));
ioSvc.run();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3044 次 |
| 最近记录: |