C ++中的双向异步通信

时间:2011-08-05 10:21:30

标签: c++ boost asynchronous boost-asio

我正在尝试用C ++实现双向异步通信。我希望能够在两台机器上指定IP地址和端口号,并能够让机器相互通信。

我看过Boost :: asio并且到目前为止已经实现了以下内容:

#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class session{
public:
  session(boost::asio::io_service& io_service) : socket_(io_service){

  }
  tcp::socket& socket(){
    return socket_;
  }
  void start(){
    socket_.async_read_some(boost::asio::buffer(data_, max_length),boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
    onConnect();
  }
  void handle_read(const boost::system::error_code& error, size_t bytes_transferred){
      if (!error){

          char* buf = boost::asio::buffer_cast<char*>(boost::asio::buffer(data_, bytes_transferred));

          char buf2[bytes_transferred];
          int n;
          n=sprintf(buf2,"%.*s",bytes_transferred,buf);
          onData(buf2);

          boost::asio::async_write(socket_, boost::asio::buffer("\0",0), boost::bind(&session::handle_write, this, boost::asio::placeholders::error));
    }else{
        delete this;
    }
  }
  void handle_write(const boost::system::error_code& error){
    if (!error){
      socket_.async_read_some(boost::asio::buffer(data_, max_length),boost::bind(&session::handle_read, this,boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
    }else{
      delete this;
    }
  }
  void onConnect(){
      printf("Connected\n");
  }
  void onData(char* buf){
      printf("%s",buf);
  }
  void write(const char* data){
      //boost::asio::async_write(socket_, boost::asio::buffer(data, strlen(data)), boost::bind(&session::handle_write, this, boost::asio::placeholders::error));
  }
private:
  tcp::socket socket_;
  enum { max_length = 1500 };
  char data_[max_length];
};

class server{
public:
  server(boost::asio::io_service& io_service, short port) : io_service_(io_service), acceptor_(io_service, tcp::endpoint(tcp::v4(), port)){
    session* new_session = new session(io_service_);
    acceptor_.async_accept(new_session->socket(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error));
  }
  void handle_accept(session* new_session, const boost::system::error_code& error){
    if (!error){
      new_session->start();
      new_session = new session(io_service_);
      acceptor_.async_accept(new_session->socket(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error));
    }else{
      delete new_session;
    }
  }
private:
  boost::asio::io_service& io_service_;
  tcp::acceptor acceptor_;
};

int main(int argc, char* argv[]){
  try{
    if (argc != 2){
      std::cerr << "Usage: async_tcp_echo_server <port>\n";
      return 1;
    }
    boost::asio::io_service io_service;

    using namespace std; // For atoi.
    server s(io_service, atoi(argv[1]));

    io_service.run();
  }catch (std::exception& e){
    std::cerr << "Exception: " << e.what() << "\n";
  }
  return 0;
}

我可以远程登录到此服务器并向其发送消息,但是如何以编程方式从远程计算机访问此服务器?我似乎无法从此代码中指定IP地址!

我希望有人可能会有一些指示。

2 个答案:

答案 0 :(得分:2)

我没有使用Boost.ASIO,但是搜索“boost asio ip address”和“boost asio gethostbyname”产生了这样的东西:

http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/reference/ip__address.html

http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/ip__tcp/resolver.html

解析器有resolve方法,可让您执行以下操作:

boost::shared_ptr< boost::asio::io_service > io_service(
    new boost::asio::io_service
);
boost::asio::ip::tcp::resolver resolver( *io_service );
boost::asio::ip::tcp::resolver::query query( 
    "www.google.com", // host string
    boost::lexical_cast< std::string >( 80 ) // port #
);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve( query );
boost::asio::ip::tcp::endpoint endpoint = *iterator;

这样就可以让你拥有一个boost::asio::tcp::endpoint,你可以在你的客户端代码的套接字连接中使用它。如果你想了解更多细节,我在这里抓住这个网站:

http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=8

答案 1 :(得分:1)

Boost.Asio pages 上有很多好的例子,可以指导您朝着正确的方向前进。

简单地说,您需要编写服务器和客户端。前者将创建连接端点,后者连接。看看这些例子。它们非常简单,易于适应您的需求。