[英]error: no member named 'write_some' with boost asio
I'm trying to send a login request to an IMAP server.我正在尝试向 IMAP 服务器发送登录请求。 I create the socket like:
我像这样创建套接字:
int main(int argc, char *argv[])
{
boost::asio::io_service ioService;
boost::asio::ssl::context sslContext(boost::asio::ssl::context::sslv23);
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslSocket(ioService, sslContext);
sslSocket.set_verify_mode(boost::asio::ssl::verify_none);
boost::asio::ip::tcp::socket::lowest_layer_type &socket = sslSocket.lowest_layer();
// Resolve endpoint and connect successfully...
std::stringstream ss;
ss << "$ LOGIN " << username << " " << password;
const char *req = ss.str().c_str();
char data[500];
strcpy(data, req);
boost::asio::write(socket, boost::asio::buffer(data, sizeof(data)));
char buffer[1000];
boost::asio::read(socket, boost::asio::buffer(buffer));
std::string response = std::string(buffer);
std::cout << "Received response: " << response << std::endl;
return 0;
}
My CMakeLists.txt looks like:我的 CMakeLists.txt 看起来像:
cmake_minimum_required(VERSION 3.16)
project(Cindel LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
add_executable(app main.cpp)
find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIRS})
target_link_libraries(app ${OPENSSL_LIBRARIES})
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost COMPONENTS system REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
target_link_libraries(app ${BOOST_LIBRARIES})
When I compile this, I get the following errors:当我编译它时,出现以下错误:
/usr/bin/clang++ -I/ -pthread -std=gnu++17 -MD -MT CMakeFiles/app.dir/main.cpp.o -MF CMakeFiles/app.dir/main.cpp.o.d -o CMakeFiles/app.dir/main.cpp.o -c /src/main.cpp
In file included from /src/main.cpp:3:
In file included from /usr/include/boost/asio/write.hpp:1246:
/usr/include/boost/asio/impl/write.hpp:54:23: error: no member named 'write_some' in 'boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>'
tmp.consume(s.write_some(tmp.prepare(max_size), ec));
~ ^
/usr/include/boost/asio/impl/write.hpp:70:18: note: in instantiation of function template specialization 'boost::asio::detail::write_buffer_sequence<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1, const boost::asio::mutable_buffer *, boost::asio::detail::transfer_all_t>' requested here
return detail::write_buffer_sequence(s, buffers,
^
/usr/include/boost/asio/impl/write.hpp:82:35: note: in instantiation of function template specialization 'boost::asio::write<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t>' requested here
std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
^
/src/main.cpp:59:18: note: in instantiation of function template specialization 'boost::asio::write<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1>' requested here
boost::asio::write(socket, boost::asio::buffer(data, sizeof(data)));
^
In file included from /src/main.cpp:2:
In file included from /usr/include/boost/asio/read.hpp:1288:
/usr/include/boost/asio/impl/read.hpp:56:23: error: no member named 'read_some' in 'boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>'
tmp.consume(s.read_some(tmp.prepare(max_size), ec));
~ ^
/usr/include/boost/asio/impl/read.hpp:72:18: note: in instantiation of function template specialization 'boost::asio::detail::read_buffer_sequence<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1, const boost::asio::mutable_buffer *, boost::asio::detail::transfer_all_t>' requested here
return detail::read_buffer_sequence(s, buffers,
^
/usr/include/boost/asio/impl/read.hpp:84:35: note: in instantiation of function template specialization 'boost::asio::read<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t>' requested here
std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);
^
/src/main.cpp:62:18: note: in instantiation of function template specialization 'boost::asio::read<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1>' requested here
boost::asio::read(socket, boost::asio::buffer(buffer));
EDIT:编辑:
My Boost version is 1.72.我的 Boost 版本是 1.72。
My updated class for making connections:我更新的 class 用于建立连接:
#include <mutex>
#include <sstream>
#include <stdexcept>
#include <string>
#include <boost/asio/read.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/buffers_iterator.hpp>
#include <boost/asio/completion_condition.hpp>
#include <boost/asio/streambuf.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <boost/asio/write.hpp>
#include <boost/system/error_code.hpp>
#include <spdlog/spdlog.h>
#include "Command.hpp"
#include "Connection.hpp"
using std::lock_guard;
using std::mutex;
using std::ostringstream;
using std::runtime_error;
using std::string;
using std::to_string;
using boost::asio::buffer;
using boost::asio::buffers_begin;
using boost::asio::buffers_end;
using boost::asio::io_context;
using boost::asio::ip::tcp;
using boost::asio::read;
using boost::asio::ssl::context;
using boost::asio::ssl::stream;
using boost::asio::streambuf;
using boost::asio::transfer_at_least;
using boost::asio::write;
using boost::system::error_code;
using cmail::imap::Command;
cmail::imap::Connection::Connection()
: ctx(new io_context()),
ssl(new context(context::sslv23)),
mtx(mutex()),
socket(*ctx, *ssl),
connected(false),
host(""),
port(0)
{
spdlog::warn("SSL verify mode is set to verify_none.");
ssl->set_verify_mode(boost::asio::ssl::verify_none);
}
cmail::imap::Connection::~Connection()
{
const lock_guard<mutex> lock(mtx);
socket.lowest_layer().cancel();
socket.lowest_layer().close();
spdlog::info("IMAP Connection closed.");
}
bool cmail::imap::Connection::open(const string &h, int p)
{
const lock_guard<mutex> lock(mtx);
if(connected) return true;
host = h;
port = p;
spdlog::trace("Resolving endpoints for " + host + ".");
error_code ec;
tcp::resolver resolver(*ctx);
tcp::resolver::query query(host, to_string(port));
tcp::resolver::iterator endpoints = resolver.resolve(query, ec);
if(ec)
{
spdlog::error("Failed to resolve endpoints for " + host + ": " + ec.message());
return false;
}
spdlog::trace("Resolved endpoints for " + host + ".");
spdlog::trace("Sending connection request to " + host + " on " + to_string(port) + ".");
tcp::resolver::iterator it = connect(socket.lowest_layer(), endpoints, ec);
if (ec)
{
spdlog::error("Failed to connect to " + host + ": " + ec.message());
return false;
}
spdlog::trace("Established connection with " + host + " on " + to_string(port) + ".");
spdlog::trace("Initiating SSL handshake with " + host + ".");
socket.handshake(stream<tcp::socket>::client, ec);
if(ec)
{
spdlog::error("SSL handshake with " + host + " failed: " + ec.message());
socket.lowest_layer().cancel();
socket.shutdown();
return false;
}
spdlog::trace("SSL handshake with " + host + " completed.");
spdlog::info("Successfully opened connection to " + host + " on " + to_string(port) + ".");
return (connected = true);
}
void cmail::imap::Connection::send(const Command &cmd)
{
const lock_guard<mutex> lock(mtx);
if(!connected)
throw runtime_error("A connection must be opened before sending requests.");
error_code ec;
spdlog::trace("C: " + cmd.text);
write(socket, buffer(cmd.text), ec);
if(ec)
{
ostringstream os;
os << "Failed to send request " << cmd.tag << " to server: " << ec.message();
string msg = os.str();
spdlog::error(msg);
throw runtime_error(msg);
}
}
void cmail::imap::Connection::receive()
{
streambuf buf;
size_t size = read(socket, buf, transfer_at_least(1));
string data(buffers_begin(buf.data()), buffers_end(buf.data()));
buf.consume(size);
spdlog::debug(data);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.