Двусторонняя асинхронная связь в C ++ - PullRequest
2 голосов
/ 05 августа 2011

Я пытаюсь реализовать двустороннюю асинхронную связь в 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;
}

Я могу telnet на этот сервер и отправлять ему сообщения, но как получить программный доступ к этому серверу с удаленного компьютера?Кажется, я не могу указать IP-адрес из этого кода!

Я надеюсь, что кто-то может иметь некоторые указатели.

Ответы [ 2 ]

2 голосов
/ 05 августа 2011

Я не использовал Boost.ASIO, но поиск «IP-адрес boost asio» и «gethostbyname boost asio» привел к этому:

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 голос
/ 05 августа 2011

Существует множество хороших примеров на Boost.Asio страниц , которые помогут вам в правильном направлении. вам нужно написать сервер и клиент .Первый создаст конечную точку для подключения, а второй подключится.Посмотрите на примеры.Они очень просты и легко адаптируются к вашим потребностям.

...