I’m trying to implement two-way asynchronous communication in C++. I’d like to be able to specify the IP address and port number on two machines and be able to get the machines to communicate with each other.
I’ve looked at Boost::asio and have implemented the following so far:
#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;
}
I can telnet into this server and send messages to it, but how to access this server programatically from a remote machine? I don’t seem to be able to specify an ip address from this code!
I hope someone might have some pointers.
I’ve not used Boost.ASIO, but searching for “boost asio ip address” and “boost asio gethostbyname” yielded this stuff:
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
The resolver has a
resolvemethod that lets you do things like:So that’ll get you to having a
boost::asio::tcp::endpointwhich you can use in your socket connection of your client code. The site where I grabbed this is here if you want more details:http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=8