我试过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结构时,服务器会写异常:无效参数
我哪里弄错了?