我已经成功构建了Boost的SSL样本,并且我已经运行它们没有明显的问题。我使用HTTP服务器和SSL示例作为参考编写了自己的代码。当我运行我的代码时,我从客户端收到了这个错误:
Handshake failed. Error: short read
这来自我的服务器:
debug: ConnectionManager::ConnectionManager()
debug: Server::Server(boost::asio::io_service&, short unsigned int)
debug: std::__cxx11::string Server::HPasswordHandler() const
debug: void Server::StartAccept()
debug: Connection::Connection(boost::asio::io_service&, boost::asio::ssl::context&, ConnectionManager&)
debug: boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >::lowest_layer_type& Connection::Socket()
debug: void Server::HAccept(const boost::system::error_code&)
debug: void Connection::Start()
debug: void Server::StartAccept()
debug: Connection::Connection(boost::asio::io_service&, boost::asio::ssl::context&, ConnectionManager&)
debug: boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >::lowest_layer_type& Connection::Socket()
Segmentation fault
debug:
是我尝试进行一些调试。当我连接到服务器时发生分段错误。
那你的想法是什么?
我的服务器代码:
#include <iostream>
#include <sstream>
#include <locale>
#include <string>
#include <set>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/thread.hpp>
inline void debug_msg(const std::string &instr) {
std::string res = "debug: ";
res += instr;
res += "\n";
std::cout << res;
std::cout.flush(); // since I don't use std::endl
}
#if defined(DEBUG) && !defined(NDEBUG)
#define _func_debug_ debug_msg(__PRETTY_FUNCTION__);
#else
#define _func_debug_
#endif
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket_t;
class ConnectionManager;
class Connection :
public boost::enable_shared_from_this<Connection> {
public:
Connection(const Connection&) = delete;
Connection &operator=(const Connection&) = delete;
explicit Connection(
boost::asio::io_service &io_service,
boost::asio::ssl::context &context,
ConnectionManager &connectionManager) :
socket_(io_service, context),
connectionManager_(connectionManager) {
_func_debug_
}
ssl_socket_t::lowest_layer_type &Socket() {
_func_debug_
return socket_.lowest_layer();
}
void Start() {
_func_debug_
socket_.async_handshake(
boost::asio::ssl::stream_base::server,
boost::bind(&Connection::HHandshake,
this,
boost::asio::placeholders::error));
}
void Stop() {
_func_debug_
socket_.lowest_layer().cancel();
socket_.shutdown();
socket_.lowest_layer().close();
}
protected:
ssl_socket_t socket_;
ConnectionManager &connectionManager_;
boost::asio::streambuf readBuffer_;
std::string message_;
void HHandshake(const boost::system::error_code &error) {
_func_debug_
if (!error) {
boost::asio::async_read_until(socket_, readBuffer_, '\0',
boost::bind(&Connection::HReadUntil, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else if (error != boost::asio::error::operation_aborted) {
NotifyConnectionManagerToStop();
}
}
void HReadUntil(
const boost::system::error_code &error,
size_t bytes_transferred) {
_func_debug_
if (!error) {
std::string s;
std::istream is(&readBuffer_);
std::getline(is, s, '\0');
std::cout << "Message: " << s << std::endl;
message_ = "Server received your message!";
message_ += std::string("", 1);
boost::asio::async_write(socket_,
boost::asio::buffer(message_, message_.size()),
boost::bind(&Connection::HWrite, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else if (error != boost::asio::error::operation_aborted) {
// if operation is aborted, connection manager
// already knows about it, since sockets
// can be stopped only by connection manager
NotifyConnectionManagerToStop();
}
}
void HWrite(
const boost::system::error_code &error,
size_t bytes_transferred) {
_func_debug_
if (!error) {
// nothing else to do.
}
else if (error != boost::asio::error::operation_aborted) {
NotifyConnectionManagerToStop();
}
}
void NotifyConnectionManagerToStop();
};
typedef boost::shared_ptr<Connection> Connection_ptr;
class ConnectionManager {
public:
ConnectionManager(const ConnectionManager&) = delete;
ConnectionManager &operator=(const ConnectionManager&) = delete;
ConnectionManager() {
_func_debug_
}
void Start(Connection_ptr connection) {
_func_debug_
connections_.insert(connection);
connection->Start();
}
void Stop(Connection_ptr connection) {
_func_debug_
connections_.erase(connection);
connection->Stop();
}
void StopAll() {
_func_debug_
for (auto connection : connections_)
connection->Stop();
connections_.clear();
}
protected:
std::set<Connection_ptr> connections_;
};
void Connection::NotifyConnectionManagerToStop() {
_func_debug_
connectionManager_.Stop(shared_from_this());
}
class Server {
public:
Server(const Server &) = delete;
Server &operator=(const Server &) = delete;
Server(
boost::asio::io_service &io_service,
unsigned short port) :
io_service_(io_service),
acceptor_(io_service,
boost::asio::ip::tcp::endpoint(
boost::asio::ip::tcp::v4(), port)),
context_(boost::asio::ssl::context::sslv23)
{
_func_debug_
context_.set_options(
boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::single_dh_use
);
context_.set_password_callback(boost::bind(&Server::HPasswordHandler,
this));
context_.use_certificate_chain_file("server.crt");
context_.use_private_key_file("server.key",
boost::asio::ssl::context::pem);
context_.use_tmp_dh_file("dh1024.pem");
StartAccept();
}
protected:
boost::asio::io_service &io_service_;
boost::asio::ip::tcp::acceptor acceptor_;
boost::asio::ssl::context context_;
ConnectionManager connection_manager_;
Connection_ptr new_connection_;
std::string HPasswordHandler() const {
_func_debug_
return "somehow return password";
}
void HAccept(const boost::system::error_code &error) {
_func_debug_
if (!error) {
new_connection_->Start();
StartAccept();
}
else {
new_connection_.reset();
}
}
void StartAccept() {
_func_debug_
new_connection_.reset(new Connection(io_service_,
context_, connection_manager_));
acceptor_.async_accept(new_connection_->Socket(),
boost::bind(&Server::HAccept, this,
boost::asio::placeholders::error));
}
};
int main(int argc, char **argv) {
try {
if (argc != 2) {
std::cerr << "Usage: PROGRAM <port>" << std::endl;
return 1;
}
boost::asio::io_service io_service;
Server server(io_service, std::atoi(argv[1]));
boost::thread t(boost::bind(&boost::asio::io_service::run,
&io_service));
std::cin.get();
io_service.stop();
t.join();
return 0;
}
catch (std::exception &e) {
std::cerr << "Exception: " << e.what() << std::endl;
return 2;
}
}
我的客户代码:
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
class Client {
protected:
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
std::string message_;
boost::asio::streambuf readBuffer_;
bool HVerifyCertificate(bool preverified,
boost::asio::ssl::verify_context &ctx) {
return preverified;
}
void HConnect(const boost::system::error_code &error) {
if (!error) {
socket_.async_handshake(boost::asio::ssl::stream_base::client,
boost::bind(&Client::HHandshake, this,
boost::asio::placeholders::error));
}
else {
std::cout << "Connect failed. Error: " <<
error.message() << std::endl;
}
}
void HReadUntil(const boost::system::error_code &error,
size_t bytes_transferred) {
if (!error) {
std::string s;
std::istream is(&readBuffer_);
std::getline(is, s, '\0');
std::cout << s << std::endl;
}
else {
std::cout << "Read failed. Error: " <<
error.message() << std::endl;
}
}
void HWrite(const boost::system::error_code &error,
size_t bytes_transferred) {
if (!error) {
boost::asio::async_read_until(socket_, readBuffer_, '\0',
boost::bind(&Client::HReadUntil, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else {
std::cout << "Write failed. Error: " <<
error.message() << std::endl;
}
}
void HHandshake(const boost::system::error_code &error) {
if (!error) {
std::cout << "To send a message type something: ";
std::getline(std::cin, message_);
message_ += std::string("", 1); // append null character
boost::asio::async_write(socket_,
boost::asio::buffer(message_, message_.size()),
boost::bind(&Client::HWrite, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else {
std::cout << "Handshake failed. Error: " <<
error.message() << std::endl;
}
}
public:
Client(boost::asio::io_service &io_service,
boost::asio::ssl::context& context,
boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
: socket_(io_service, context) {
socket_.set_verify_mode(boost::asio::ssl::verify_peer);
socket_.set_verify_callback(boost::bind(&Client::HVerifyCertificate,
this, _1, _2));
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&Client::HConnect, this,
boost::asio::placeholders::error));
}
};
int main(int argc, char **argv) {
try {
if (argc != 3) {
std::cerr << "Usage: PROGRAM <host> <port>" << std::endl;
return 1;
}
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(argv[1], argv[2]);
boost::asio::ip::tcp::resolver::iterator iterator =
resolver.resolve(query);
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
ctx.load_verify_file("server.crt");
Client client(io_service, ctx, iterator);
io_service.run();
return 0;
}
catch (std::exception &e) {
std::cerr << "Exception: " << e.what() << std::endl;
return 1;
}
}
答案 0 :(得分:0)
嗯,这是一个简单的错误。我忘了通过连接管理器启动新连接,因此我的连接对象被删除,并且我收到了分段错误。问题解决了。 :d