Сервер Boost / Asio получает неверный аргумент Переполнение стека

Я старался этот пример, работает правильно. Но я хочу, чтобы сервер = получатель и клиент = отправитель, поэтому я старался переписать этот пример как динамическую библиотеку.

Сервер:

Server::Server(protocol::Service& io_service, unsigned short port) : acceptor_(io_service, protocol::Endpoint(boost::asio::ip::tcp::v4(), port))
{
connectionPtr newConn(new Connection(acceptor_.io_service()));
acceptor_.async_accept(newConn->socket(), boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error, newConn));
}void Server::HandleAccept(const boost::system::error_code &e, connectionPtr conn)
{
if(!e) {
conn->AsyncRead(pkg, boost::bind(&Server::HandleRead, this, boost::asio::placeholders::error));
connectionPtr newConn(new Connection(acceptor_.io_service()));
acceptor_.async_accept(newConn->socket(), boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error, newConn));
}

else {
std::cerr << e.message() << std::endl;
}
}

void Server::HandleRead(const boost::system::error_code &e)
{
if(!e) {
for(std::size_t i = 0; i < pkg.size(); i++) {
std::cout << "Package Number " << i << std::endl;
std::cout << "ID: " << pkg[i].uuId << std::endl;
std::cout << "GENDER: " << pkg[i].gender << std::endl;
}
}
else {
std::cerr << e.message() << std::endl;
}
}

Клиент:

Client::Client(protocol::Service &io_service, const std::string &host, const std::string &service, Package stock) : connection_(io_service)
{
// Resolve the host name into an IP address.
protocol::Resolver resolver(io_service);
protocol::ResolverQuery query(host, service);
protocol::ResolverIter endpointIter = resolver.resolve(query);
protocol::Endpoint endpoint = *endpointIter;

pkg.push_back(stock);

// Start an asynchronous connect operation.
connection_.socket().async_connect(endpoint, boost::bind(&Client::HandleConnect, this, boost::asio::placeholders::error, ++endpointIter));
}

void Client::HandleConnect(const boost::system::error_code &e, protocol::ResolverIter endpointIter)
{
if(!e) {
connection_.AsyncWrite(pkg, boost::bind(&Client::HandleWrite, this, boost::asio::placeholders::error(), conn));
}
else if(endpointIter != protocol::ResolverIter()) {
connection_.socket().close();
protocol::Endpoint endpoint = *endpointIter;

connection_.socket().async_connect(endpoint, boost::bind(&Client::HandleConnect, this, boost::asio::placeholders::error(), ++endpointIter));
}
else{
std::cerr << e.message() << std::endl;
}
}

void Client::HandleWrite(const boost::system::error_code &e, connectionPtr conn)
{
std::cout << "Sent Files: " << std::endl;
std::cout << "ID: " <<  pkg.front().uuId << std::endl;
}

connection.h:

class Connection : public boost::enable_shared_from_this<Connection>{
public:
Connection(protocol::Service& io_service) : socket_(io_service) {}
protocol::Socket& socket(){
return socket_;
}

template <typename T, typename Handler>
void AsyncWrite(const T& t, Handler handler)
{
std::ostringstream archiveStream;
boost::archive::text_oarchive archive(archiveStream);
archive << t;
outboundData = archiveStream.str();

// Format the header.
std::ostringstream headerStream;
headerStream << std::setw(headerLength) << std::hex << outboundData.size();

if (!headerStream || headerStream.str().size() != headerLength)
{
// Something went wrong, inform the caller.
boost::system::error_code error(boost::asio::error::invalid_argument);
socket_.io_service().post(boost::bind(handler, error));
return;
}

outboundHeader = headerStream.str();

// Write the serialized data to the socket. We use "gather-write" to send
// both the header and the data in a single write operation.

std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(boost::asio::buffer(outboundHeader));
buffers.push_back(boost::asio::buffer(outboundData));
boost::asio::async_write(socket_, buffers, handler);
}template <typename T, typename Handler>
void AsyncRead(T& t, Handler handler)
{
// Issue a read operation to read exactly the number of bytes in a header.
void (Connection::*f)(const boost::system::error_code&, T&, boost::tuple<Handler>) = &Connection::HandleReadHeader<T, Handler>;
boost::asio::async_read(socket_, boost::asio::buffer(inboundHeader),
boost::bind(f, shared_from_this(), boost::asio::placeholders::error, boost::ref(t), boost::make_tuple(handler)));
}template <typename T, typename Handler>
void HandleReadHeader(const boost::system::error_code& e, T& t, boost::tuple<Handler> handler)
{
if (e)
boost::get<0>(handler)(e);
else {
// Determine the length of the serialized data.
std::istringstream is(std::string(inboundHeader, headerLength));
std::size_t inboundDataSize = 0;

if (!(is >> std::hex >> inboundDataSize)) {
// Header doesn't seem to be valid. Inform the caller.
boost::system::error_code error(boost::asio::error::invalid_argument);
boost::get<0>(handler)(error);
return;
}

// Start an asynchronous call to receive the data.
inboundData.resize(inboundDataSize);
void (Connection::*f)(const boost::system::error_code&,T&, boost::tuple<Handler>) = &Connection::HandleReadData<T, Handler>;
boost::asio::async_read(socket_, boost::asio::buffer(inboundData), boost::bind(f, this, boost::asio::placeholders::error, boost::ref(t), handler));
}
}template <typename T, typename Handler>
void HandleReadData(const boost::system::error_code& e, T& t, boost::tuple<Handler> handler)
{
if (e)
boost::get<0>(handler)(e);
else {
// Extract the data structure from the data just received.
try {
std::string archiveData(&inboundData[0], inboundData.size());
std::istringstream archiveStream(archiveData);
boost::archive::text_iarchive archive(archiveStream);
archive >> t;
}
catch (std::exception& e)
{
// Unable to decode data.
boost::system::error_code error(boost::asio::error::invalid_argument);
boost::get<0>(handler)(error);
return;
}

// Inform caller that data has been received ok.
boost::get<0>(handler)(e);
}
}private:
protocol::Socket socket_;
enum { headerLength = 8 };
std::string outboundHeader;
std::string outboundData;
char inboundHeader[headerLength];
std::vector<char> inboundData;
};

typedef boost::shared_ptr<Connection> connectionPtr;

Я создал 2 проекта (Сервер & Клиент) и включил эту динамическую библиотеку. Когда клиент отправляет структуру пакета, сервер пишет исключение: неверный аргумент

Где я ошибся?

0

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]