Boost / Asio Server获取无效的参数C ++

时间:2014-09-04 12:36:07

标签: c++ boost boost-asio invalid-argument

我试过this示例,工作正常。但我想要server = receiver和client = sender,所以我盯着把这个例子重写为动态库。

服务器:

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个项目(Server&amp; Client)并包含了这个动态库。当客户端发送Package结构时,服务器会写异常:无效参数

我哪里弄错了?

0 个答案:

没有答案