user3790646
user3790646

Reputation:

Connecting to a domain to host a server with Boost.Asio

How can I connect to my domain through my server, so that I can "host" it?

I've tried changing the code snippet below to match the IP with my domain's name, but a exception is caught saying that a invalid argument was supplied, I assumed I should resolve the domain name, get the IP and use the IP I got and not the one in the code snippet below, but it seems like I'm connecting to my external IP, and this doesn't let me host the server, as it says the machine actively refused the connection.

That's the code snippet:

boost::asio::ip::tcp::acceptor acceptor(service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("192.168.1.3"), 8001));

That's the full code:

Main.cpp

#include "Server.h"

#include <string>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

int main()
{
    Server server;
    boost::thread([&server] {
        server.handleConnections();
    }).join();

    return 0;
}

Server.h

#ifndef SERVER_H
#define SERVER_H

#include <string>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

class Server
{
private:
    boost::asio::io_service service;
    boost::asio::ip::tcp::socket sock;
protected:

public:
    Server() : service(), sock(service) {

    }

    ~Server() {

    }

    void handleConnections();
};

#endif

Server.cpp

#include "Server.h"

void Server::handleConnections() {
    boost::system::error_code err;
    try {
        boost::asio::ip::tcp::acceptor acceptor(service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("192.168.1.3"), 8001));
        std::cout << acceptor.local_endpoint(err) << std::endl;
        while (true) {
            sock = boost::asio::ip::tcp::socket(service);
            boost::system::error_code errCode;
            acceptor.accept(this->sock, acceptor.local_endpoint(), errCode);
            boost::asio::write(sock, boost::asio::buffer("Olá"), errCode);
        }
        this->sock.close();
    }
    catch (std::exception & e)
    {
        std::cout << e.what();
    }
}

Upvotes: 1

Views: 1227

Answers (1)

sehe
sehe

Reputation: 393134

  1. Firstly

    acceptor.accept(this->sock, acceptor.local_endpoint(), errCode);
    

    The documentation says:

    This function is used to accept a new connection from a peer into the given socket, and additionally provide the endpoint of the remote peer. The function call will block until a new connection has been accepted successfully or an error occurs.

    You ... pass the acceptor's local endpoint as the endpoint to receive the peer's remote endpoint (I'm surprised if that compiles). That makes little sense. I suggest you don't need to know the remote endpoint¹:

    acceptor.accept(this->sock, errCode);
    
  2. Secondly, you've bound to the loopback adaptor:

    boost::asio::ip::tcp::acceptor acceptor(service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("192.168.1.3"), 8001));
    

    This directly implies you cannot access it from the network². Change it to be NIC-agnostic:

    tcp::acceptor acceptor(service, tcp::endpoint(ip::address(), 8001));
    

¹ you can usually get it from the socket later using socket_->remote_endpoint() unless the socket has become invalid (e.g. closed)

² unless you implement some funky routing/tunneling logic, which is far stretch

UPDATE

Self contained demo with error handling:

Live On Coliru

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

class Server
{
    boost::asio::io_service service;
public:
    void handleConnections() 
    {
        using namespace boost::asio;

        boost::system::error_code err;

        try {
            ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::address(), 6768));

            std::cout << acceptor.local_endpoint(err) << std::endl;

            while (!err) {
                ip::tcp::socket sock(service);

                if (   !acceptor.accept(sock, err)
                    && !write(sock, buffer("Olá"), err)
                    && !sock.close(err))
                {
                    std::cout << "Error in connection: " << err << " " << err.message() << "\n";
                }
            }
        } catch (std::exception & e) {
            std::cout << e.what();
        }
    }
};

#include <boost/thread.hpp>

int main() {
    Server server;
    boost::thread([&server] { server.handleConnections(); }).join();
}

Output:

$ ./a.out& 
0.0.0.0:6768

$ while sleep 1; do nc 127.0.0.1 6768; done
OláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOláOlá

Upvotes: 1

Related Questions