简体   繁体   English

错误:没有名为“write_some”的成员使用 boost asio

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM