Click here to Skip to main content
15,881,424 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am facing a strange issue while trying to resolve endpoints using boost resolver in c++.

Case:
I am trying to connect to a website http://localhostIpAddress/test/ using boost.
where local address of server is "172.34.22.11"(say).

I am facing the error saying "**resolve: No such host is known**"

But when I am connecting to say website like google.com its able to resolve and connect successfully.
Also,even when I try to open "http:://localhostIpAddress/test/" in a browser, it opens successfully.

below is my code:
C++
    int main()
    {
    		std::cout << "\nWebClient  is starting... \n";
    		boost::asio::io_service IO_Servicehttp;
    		boost::asio::ip::tcp::resolver Resolverhttp(IO_Servicehttp);
    		std::string porthttp = "http";
    		boost::asio::ip::tcp::resolver::query Queryhttp("172.34.22.11/test/", porthttp);  
    		boost::asio::ip::tcp::resolver::iterator EndPointIteratorhttp = Resolverhttp.resolve(Queryhttp);
    
    		g_ClientHttp = new HTTPClient(IO_Servicehttp, EndPointIteratorhttp);
    
    	}
    	catch (std::exception& e)
    	{
    		std::cerr << e.what();
    	}
    }

In HTTPClient.cpp

    HTTPClient::HTTPClient(boost::asio::io_service& IO_Servicehttp, boost::asio::ip::tcp::resolver::iterator EndPointIterhttp)
    : m_IOServicehttp(IO_Servicehttp), m_Sockethttp(IO_Servicehttp),m_EndPointhttp(*EndPointIterhttp)
    {
    	std::cout << "\n Entered: HTTPClient ctor \n";
    	boost::asio::ip::tcp::resolver::iterator endhttp;
    	boost::system::error_code error= boost::asio::error::host_not_found;
    
    	try
    	{
    		while (error && EndPointIterhttp != endhttp) //if error go to next endpoint
    		{
    			m_Sockethttp.async_connect(m_EndPointhttp,boost::bind(&HTTPClient::OnConnect_http, this, boost::asio::placeholders::error, ++EndPointIterhttp));
    		}
    		if(error)
    			throw boost::system::system_error(error);
    	}
    
    	catch (std::exception& e)
    	{
    		std::cerr << e.what() << std::endl;
    	}
    	m_IOServicehttp.run();
    }

I have gone through a lot of website directed by google but haven't found anything related to this issue.
Any help or tip will be much appreciated

What I have tried:

I have tried putting hosname "172.34.22.11" , which I am able to resolve but my requirement is to connect to "http://172.34.22.11/test" and send some data to it.
But I am unable to resolve the host name.
Posted
Updated 12-Mar-16 3:51am
v2
Comments
Richard MacCutchan 4-Mar-16 4:25am    
Do you have an HTTP server running at that address that can resolve the page 'test'?
Member 10305620 4-Mar-16 5:33am    
Yes, HTTP server is running at the address.
Not sure why it is not able to resolve host name when concatenated with address/webpage.
Richard MacCutchan 4-Mar-16 5:37am    
Maybe it requires just the host name/ip address. Have you checked the documentation?
Member 10305620 4-Mar-16 5:48am    
I have checked the documentation but didn't get any such information.But yeah, I see they send some Get request for which server replies.But Since its a web server running on a remote computer which I wanted to connect to and send some data, hence I was trying to provide the complete server path.
Richard MacCutchan 4-Mar-16 5:50am    
The word test is not part of the server name, it is a page reference for the HTTP server. That is most likely your problem.

1 solution

when you use raw sockets to implement a protocol

for HTTP you need to follow the steps below

Note : i will use code parts from the sample link you have provided (without testing myself)

first find target end point ,you need an IP address and port (default 80 for HTTP) can also be 8080 or any for dedicated services
If you have a domain name or just a host name you need to resolve this to obtain IP address
If you have a URL such as http://domain.com/services/api you can not pass this URL to resolver directly
You must use only domain name http://domain.com so you need to split this URL to 2 parts as host and resource

consider following; i have 2 variables as domain and resource and passing domain variable to resolver
C++
std::string domain = "http://domain.com";
std::string resource = "/services/api";

boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(domain, "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

And here i am connecting to the server
C++
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);

once the connection established you can use it for other transactions

and the further navigation will be made with headers
A HTTP packed consist of 3 parts : status/request line ,headers ,content

status/request line
header-field:value
header-field:value
header-field:value
header-field:value

content


Now you need to contruct a request header , request specified resource from server
You have to provide Host field in request header ,resource can not be found otherwise
because server uses that to map local file path to requested resource
consider a web server at IP 123.123.123.123 and there are 100 shared host accounts (web sites) under a CP
if you do not provide host name you will reach default landing page of server/CP

you can also add other http headers to qualify your request

C++
std::string domain = "http://domain.com";
std::string resource = "/services/api";
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << resource << " HTTP/1.0\r\n";
request_stream << "Host: " << domain << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: keep-alive\r\n\r\n";

boost::asio::write(socket, request);

If you noticed that there is a extra (empty) line at the end of header \r\n that tells server there is no more headers to read
For a simple GET request you do not need to send a content

Now time has come to get response ,validate the response by cheking the response line
See if you have recevied a status code other than 200 , or something other than a http response

C++
boost::asio::streambuf response;
boost::asio::read_until(socket, response, "\r\n");
std::istream response_stream(&response);

std::string http_version;
response_stream >> http_version;
unsigned int status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
     std::cout << "Invalid response\n";
      return 1;
    }
    if (status_code != 200)
    {
      std::cout << "Response returned with status code " << status_code << "\n";
      return 1;
    }
}


Now read response headers ,check content type ,encoding ,length etc..
C++
boost::asio::read_until(socket, response, "\r\n\r\n");

  
   std::string header;
   while (std::getline(response_stream, header) && header != "\r")
     std::cout << header << "\n";
   std::cout << "\n";


finally the response variable contains the content that you expected to receive from server
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900