HTTP 'GET' request from C++ client app

  1. #1
    Cache is offline Super Moderator

    HTTP 'GET' request from C++ client app

    I made a C++ client app, which seems to work well. It's sending/receiving bytes just fine. The problem I'm having is requesting web pages from servers. I don't know how to retrieve files from sub domains (I think that's what they are lol).

    Say I have the IP of a server: 70.84.66.196 (Cameron's server) -- I have a char array with a HTTP GET request:

    char sendbuf[57] = "GET /index.php\nHost: www.techhelpforum.com\n";

    What I'm getting is the "Three Poor Guys" index, not THF. See what I'm getting at?

    I think the problem is my escape sequences. Any Ideas how make this work? I need the GET request to be all in one string too, btw.

    Thanks,
    Cache.

  2. #2
    Techie-Micheal is offline Super Moderator
    s/Cameron\'s/TPG\'s/

    I am still 1/3 owner of it.

    Without seeing the full code, I can't tell you why it isn't working. But what you posted should work from a glance.

  3. #3
    Cache is offline Super Moderator
    Here is the full client code:

    Code:
    #include <winsock2.h>
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    // Client
    
    int main() {
    
        WSADATA wsaData;
        int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
        if ( iResult != NO_ERROR ) { cout << "Error at WSAStartup()\n"; }
    
        SOCKET m_socket;
        m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    
        if ( m_socket == INVALID_SOCKET ) 
        {
            cout << "Error at socket(): " << WSAGetLastError();
            WSACleanup();
            system ("PAUSE");
            return 0;
        }
    
        sockaddr_in clientService;
    
        clientService.sin_family = AF_INET;
        clientService.sin_addr.s_addr = inet_addr( "70.84.66.196" );
        clientService.sin_port = htons( 80 );
    
        if ( connect( m_socket, (SOCKADDR*) &clientService, 
                      sizeof(clientService) ) == SOCKET_ERROR) 
        {
            cout << "Failed to connect.\n";
            WSACleanup();
            system("PAUSE");
            return 0;
        }
    
        int bytesSent;
        int bytesRecv = SOCKET_ERROR;
        char sendbuf[100] = "GET /somethinghere\n";   // <--What GET request?
        char recvbuf[10000] = "";
    
        bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
        cout << "Bytes Sent: " << bytesSent << endl;
    
        
        if (!bytesRecv == 0 || 
            (bytesRecv == SOCKET_ERROR && 
             WSAGetLastError()== WSAECONNRESET ))
        {
            bytesRecv = recv( m_socket, recvbuf, 10000, 0 );
            if ( bytesRecv == -1 ) { cout << "Connection Closed.\n"; }
            cout << "Bytes Recv: " << bytesRecv << endl;
            cout << "\n" << recvbuf << endl;
        }
        
        string File = recvbuf;
        ofstream outFile;
        
        outFile.open("index.php");
        outFile << File;
        outFile.close();
        
        system("PAUSE");
        return 0;
    }
    Keep in mind this client does actually work, it's just figuring out what GET request to use for getting pages from sub domains (or whatever they are) that's a problem.

    EDIT: If you want to compile this you will need to link the lib file: WS2_32.Lib
    It comes with the Platform SDK.

  4. #4
    Techie-Micheal is offline Super Moderator
    Sometime this week the SDK will finish installing ...

  5. #5
    Techie-Micheal is offline Super Moderator
    Hm. I can get it to send bytes, but it isn't receiving ... Anywho, try this:

    Code:
    #include <winsock2.h>
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    // Client
    
    int main()
    {
     	WSADATA wsaData;
    
    	int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
    
    	if ( iResult != NO_ERROR )
    	{
    	   	 cout << "Error at WSAStartup()\n";
    	}
    
    	SOCKET m_socket;
    
    	m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    
    	if ( m_socket == INVALID_SOCKET ) 
    	{
    	   cout << "Error at socket(): " << WSAGetLastError();
    	   WSACleanup();
    	   system ("PAUSE");
    	   return 0;
    	}
    
    	sockaddr_in clientService;
    
        clientService.sin_family = AF_INET;
        clientService.sin_addr.s_addr = inet_addr( "70.84.66.196" );
        clientService.sin_port = htons( 80 );
    
        if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) 
        {
            cout << "Failed to connect.\n";
            WSACleanup();
            system("PAUSE");
            return 0;
        }
    
        int bytesSent;
        int bytesRecv = SOCKET_ERROR;
        char sendbuf[100] = "GET / HTTP/1.1\nHost: www.spsac.net\n";   // <--What GET request?
        char recvbuf[10000] = "";
    
        bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
        cout << "Bytes Sent: " << bytesSent << endl;
    
        if (!bytesRecv == 0 || (bytesRecv == SOCKET_ERROR && WSAGetLastError()== WSAECONNRESET ))
        {
            bytesRecv = recv( m_socket, recvbuf, 10000, 0 );
            
    		if ( bytesRecv == -1 ) 
    		{
    		   	 cout << "Connection Closed.\n";
    		}
            
    		cout << "Bytes Recv: " << bytesRecv << endl;
            cout << "\n" << recvbuf << endl;
        }
        
        string File = recvbuf;
        ofstream outFile;
        
        outFile.open("index.php");
        outFile << File;
        outFile.close();
        
        system("PAUSE");
        return 0;
    }

  6. #6
    Cache is offline Super Moderator
    It will receive bytes if you remove the 'HTTP/1.1' from your GET request. But again this only gets the "Three Poor Guys" index. I'm pretty sure that's because anything after the first '\n' is being ignored.

  7. #7
    Cache is offline Super Moderator
    Just an update. If I can't get this to work any time soon, I'll look into the Platform SDK WinINet API functions. That seems somewhat overly complicated for such a simple task, though.:roll:

    http://msdn.microsoft.com/library/de...net/portal.asp

  8. #8
    Cache is offline Super Moderator
    I've finally figured it out::

    char sendbuf[] = "GET http://www.techhelpforum.com/index.php\n";


    I can't believe that wasn't one of the first things I tried lol. I got this from the "Request" section of the HTTP/1.1 RFC 2616 -- which suggests you could be using some sort of proxy?. What's odd still, is that even the RFC specifies the request to a proxy should be:

    GET http://www.techhelpforum.com/index.php HTTP/1.1

    Note the HTTP part at the end. For some reason I never get a response if I pop the HTTP bit in the request string.

  9. #9
    Tyler D-A-L Guest
    Glad you got it Cache! :thumbs:

+ Reply to Thread