Thread: My Client Socket Program not receiving response

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Sep 2022
    Posts
    11

    My Client Socket Program not receiving response

    I created a simple http client socket program that fetches data via a GET Request. Sadly, it does not seem to be returning a http response (it seems to freeze). The request appears t be valid and the http protocol version is 1.1. Here is the code in C++


    Code:
    #include <fstream>
    
    #include <iostream>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    string resolveToIPAddress(string, string);
    int getPortNum(string);
    string getUrlPath(string);
    string getDomain(string);
    string getDomainWithFile(string);
    string getUrlWithNoPort(string);
    string getFileFromURL(string);
    bool hasHTTPProtocol(string);
    bool hasPortNum(string);
    bool checkIfValidIPAddress(string);
    
    int main(int argc, char **argv)
    {
      //Create a file to be opened for output
      ofstream out_file;
      out_file.open("output.txt", ios::out);
      int connection_port = 0, send_req, recv_req;
      string ip_addr = "", domain = "", ipFromDomain = "", file_to_get = "";
      ip_addr = argv[1];            //point ip address argument to the 2nd indice in the arguments
    
    
      //if there is a port number, Get port number (extract it from URL)
      if (hasPortNum(ip_addr)) {
        connection_port = getPortNum(ip_addr);
        domain = getDomain(ip_addr);
      }
      //if there is no port number, set default port number = 80 and set domain to truncated ip address
      else {
        connection_port = 80;
        domain = getDomain(ip_addr);
      }
    
      file_to_get = getFileFromURL(ip_addr);
      cout << "Domain: " << domain << endl;
      cout << "Port Number: " << connection_port << endl;
      cout << "File requested: " << file_to_get << endl;
      //resolve domain to ipAddress
      ipFromDomain = resolveToIPAddress(domain, to_string(connection_port));
      //Connect to iP Address with port and return metadata
    
      //Create the socket
      int http_client_socket = socket(AF_INET, SOCK_STREAM, 0);
    
      // connect address and contain socket
      struct sockaddr_in connection_addr;
      connection_addr.sin_family = AF_INET; //set the addressfamily type to INET 
      connection_addr.sin_port = htons(connection_port);  //set socket to parsed port number
      cout << "ip address: " << ipFromDomain << endl; //checking to see if ip address is well converted
      inet_aton(ipFromDomain.c_str(), &connection_addr.sin_addr); //convert ip address from IPV4 notation string and store it into structure
    
      //Connect to server address
      if (connect
          (http_client_socket, (struct sockaddr *) &connection_addr,
           sizeof(connection_addr)) != 0) {
        cout << "Connection with the server failed..." << endl;
        exit(0);
      }
      //Logic for HTTP GET Request
      string http_request = "GET /" + file_to_get + " HTTP/1.1\r\n\r\n";
      cout << http_request << endl;
      //string http_response;
      string http_response;
    
      send(http_client_socket, http_request.c_str(), sizeof(http_request), 0);
      recv(http_client_socket, &http_response, 999999999, 0);
    
      out_file << http_response << endl;
    
      //close the file
      out_file.close();
    
      //close the socket
      close(http_client_socket);
      return 0;
    }
    
    string getUrlWithNoPort(string url)
    {
      if (hasHTTPProtocol(url))
        return url.substr(7, url.length() - 7);
      return url;
    }
    
    //Get URL without port and path
    string getDomain(string url)
    {
      string urlWithoutPortandPath = "";
      int i = 0;
      //Check if full URL has a protocol
      if (hasHTTPProtocol(url)) {
        //if it has a protocol truncate the protocol from FQDN
        i = 7;
        while (url != '/') {
    
    
          //for (int i = 7; i < url.length(); i++) {
          if (url == ':') {
            break;
          }
          urlWithoutPortandPath += url;
          i++;
          //}
        }
        return urlWithoutPortandPath;
      }
      //if it does not have a protocol remove port number and path
      while (url != '/') {
        //for (int i = 0; i < url.length(); i++) {
        if (url == ':') {
          break;
        }
        urlWithoutPortandPath += url;
        i++;
      }
      return urlWithoutPortandPath;
    }
    
    string getDomainWithFile(string url)
    {
      string urlWithoutPortandPath = "";
      //Check if full URL has a protocol
      if (hasHTTPProtocol(url)) {
        //if it has a protocol truncate the protocol from FQDN
        for (int i = 7; i < url.length(); i++) {
          if (url == ':') {
            break;
          }
          urlWithoutPortandPath += url;
        }
        return urlWithoutPortandPath;
      }
      //if it does not have a protocol remove port number and path
    
      for (int i = 0; i < url.length(); i++) {
        if (url == ':') {
          break;
        }
        urlWithoutPortandPath += url;
      }
      return urlWithoutPortandPath;
    }
    
    bool hasHTTPProtocol(string url)
    {
      string httpProtocol = url.substr(0, 7);
      if (httpProtocol == "http://")
        return true;
      return false;
    }
    
    int getPortNum(string url)
    {
      string port = "";
      int portNum, portIdx = 0, pathIdx = 0, portEndIdx = 0;
      if (hasHTTPProtocol(url)) {
        for (int i = 7; i < url.length(); i++) {
          if (url == ':')
            portIdx = i + 1;
        }
      }
    
    
      string fromPortToPath = url.substr(portIdx, url.length() - portIdx);
      cout << "Port to Path: " << fromPortToPath << endl;
    
      for (int i = 0; i < fromPortToPath.length(); i++) {
        if (fromPortToPath == '/') {
          pathIdx = i + 1;
          portEndIdx = i;
          break;
        }
      }
      port = fromPortToPath.substr(0, portEndIdx);
      portNum = stoi(port);
      return portNum;
    }
    
    string getUrlPath(string url)
    {
      string urlPath = "";
      int pathIdx = 0, portIdx = 0, portEndIdx = 0;
      if (hasHTTPProtocol(url)) {
        for (int i = 7; i < url.length(); i++) {
          if (url == ':')
            portIdx = i + 1;
        }
      }
    
      string fromPortToPath = url.substr(portIdx, url.length() - portIdx);
      cout << "Port to Path: " << fromPortToPath << endl;
    
      for (int i = 0; i < fromPortToPath.length(); i++) {
        if (fromPortToPath == '/') {
          pathIdx = i + 1;
          portEndIdx = i;
          break;
        }
      }
      urlPath =
          fromPortToPath.substr(portEndIdx + 1, fromPortToPath.length() - pathIdx);
      return urlPath;
    }
    
    bool hasPortNum(string url)
    {
      if (hasHTTPProtocol(url)) {
        for (int i = 7; i < url.length(); i++) {
          if (url == ':')
            return true;
        }
      } else {
        for (int i = 0; i < url.length(); i++) {
          if (url == ':')
            return true;
        }
      }
    
      return false;
    }
    
    //Resolves a string hostname e.g. google.com into an ipaddress (practically a DNS function)
    string resolveToIPAddress(string urlString, string portNum)
    {
      struct addrinfo hints, *results;
      struct addrinfo *result;
      int error, sock_id;
      string numericalIPS[100];
      //set all bits in hints to zero
      memset(&hints, 0, sizeof(hints));
      hints.ai_family = AF_INET;
      hints.ai_socktype = SOCK_STREAM;
    
      if ((error =
           getaddrinfo(urlString.c_str(), portNum.c_str(), &hints,
                       &results)) != 0) {
        cout << "error " << error << ":" << gai_strerror(error) << endl;
      }
    
      int i = 0;
      //loop through results
      for (result = results; result != nullptr; result = result->ai_next) {
        struct sockaddr_in *ip_addr;
        ip_addr = (struct sockaddr_in *) result->ai_addr;
        numericalIPS = inet_ntoa(ip_addr->sin_addr);
        i++;
      }
      return numericalIPS[0];
    }
    
    string getFileFromURL(string url)
    {
      int idxToFile;
      string file_request;
      string path_to_file = getDomainWithFile(url);
      for (int i = 0; i < path_to_file.length(); i++) {
        if (path_to_file == '/') {
          idxToFile = i + 1;
        }
      }
      file_request =
          path_to_file.substr(idxToFile, path_to_file.length() - idxToFile);
      return file_request;
    }
    I took the following measures to debug the application:

    1. Stepping through the code
    2. adding print statements to make sure that the domain, port number, the ip address the domain resolves to via DNS, and the file that is requested are correct...They appear to be.


    The way I dissected the data one by one is by getting the domain, port number, path to the file. I went ahead and used DNS to resolve the hostname to an IPv4 address. I am still running into problems. Thanks!
    Last edited by Salem; 09-26-2022 at 03:28 AM. Reason: removed crayola

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Client Socket Program to connect to SSH Server
    By emmaclark in forum C Programming
    Replies: 4
    Last Post: 12-27-2016, 03:09 AM
  2. C / Unix: client program with listeninig socket
    By YocR in forum Networking/Device Communication
    Replies: 4
    Last Post: 08-16-2013, 01:27 AM
  3. not receiving messages in server/client program
    By ueg1990 in forum C Programming
    Replies: 5
    Last Post: 07-08-2012, 07:57 PM
  4. writing a client program - socket programming Linux
    By rehman12390 in forum Linux Programming
    Replies: 4
    Last Post: 01-08-2012, 04:18 PM
  5. Replies: 10
    Last Post: 01-27-2010, 01:20 AM

Tags for this Thread