Simple HTTP Get with Winsock

14,845

Hard to say...

Here is a simple and generic piece of winsock code you can try, just to see if the problem also exists when using this code.

#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <locale>
#include <sstream>
using namespace std;
#pragma comment(lib,"ws2_32.lib")


string website_HTML;
locale local;
void get_Website(string url );
char buffer[10000];
int i = 0 ;


 //****************************************************

int main( void ){

    get_Website("www.stackoverflow.com" );

    cout<<website_HTML;

    cout<<"\n\nPress ANY key to close.\n\n";
    cin.ignore(); cin.get(); 


 return 0;
}

 //****************************************************

void get_Website(string url ){
    WSADATA wsaData;
    SOCKET Socket;
    SOCKADDR_IN SockAddr;
    int lineCount=0;
    int rowCount=0;
    struct hostent *host;
    string get_http;


    get_http = "GET / HTTP/1.1\r\nHost: " + url + "\r\nConnection: close\r\n\r\n";

    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){
        cout << "WSAStartup failed.\n";
        system("pause");
        //return 1;
    }

    Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    host = gethostbyname(url.c_str());

    SockAddr.sin_port=htons(80);
    SockAddr.sin_family=AF_INET;
    SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

    if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0){
        cout << "Could not connect";
        system("pause");
        //return 1;
    }
    send(Socket,get_http.c_str(), strlen(get_http.c_str()),0 );

    int nDataLength;
    while ((nDataLength = recv(Socket,buffer,10000,0)) > 0){        
        int i = 0;
        while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r'){

            website_HTML+=buffer[i];
            i += 1;
        }               
    }

    closesocket(Socket);
    WSACleanup();

}
Share:
14,845
Admin
Author by

Admin

Updated on June 15, 2022

Comments

  • Admin
    Admin almost 2 years

    Some time ago, I made a very simple method that could make an http request and return a response. This worked like I intended but now I want to use it again but I've suddenly ran into an issue I can't seem to figure out. Every time I make a request, it returns error 503: Service Unavailable.

    Sometimes it works, sometimes it doesn't.

    I noticed if I put a breakpoint after the shutdown of the connection and wait just a little and continue, there is no problem and everything works. So my guess is that this has something to do with timing/delay of the server.

    Does anyone have experience with this?

    Thanks in advance!

    string HttpHelper::HttpGet(string host, string path)
    {
        WSADATA wsaData;
        int result;
    
        // Initialize Winsock
        result = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (result != 0)
            throw SocketError(L"WSAStartUp", result);
    
        // Resolve the server address and port
        addrinfo * pAddrInfo;
        result = getaddrinfo(host.c_str(), "80", 0, &pAddrInfo);
        if (result != 0)
            throw SocketError(L"addrinfo", result);
    
        //Create the socket
        SOCKET sock = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, pAddrInfo->ai_protocol);
    
        if (sock == INVALID_SOCKET)
            throw SocketError(L"Socket", WSAGetLastError());
    
        // Connect to server.
        result = connect(sock, pAddrInfo->ai_addr, pAddrInfo->ai_addrlen);
        if (result != 0)
            throw SocketError(L"Connect", WSAGetLastError());
    
        const string request = "GET " + path + " HTTP/1.1\nHost: " + host + "\n\n";
    
        // Send an initial buffer
        result = send(sock, request.c_str(), request.size(), 0);
        if (result == SOCKET_ERROR)
            throw SocketError(L"Send", WSAGetLastError());
    
        // shutdown the connection since no more data will be sent
        result = shutdown(sock, SD_SEND);
        if (result == SOCKET_ERROR)
            throw SocketError(L"Close send connection", WSAGetLastError());
    
        // Receive until the peer closes the connection
        string response;
    
        char buffer[50];
        int bytesRecv = 0;
    
        for (;;)
        {
            result = recv(sock, buffer, sizeof(buffer), 0);
            if (result == SOCKET_ERROR)
                throw SocketError(L"Recv", WSAGetLastError());
            if (result == 0)
                break;
            response += string(buffer, result);
            wstringstream stream;
            stream << L"HttpGet() > Bytes received: " << bytesRecv;
            DebugLog::Log(stream.str(), LogType::INFO);
            bytesRecv += result;
        }
        wstringstream stream;
        stream << L"HttpGet() > Bytes received: " << bytesRecv;
        DebugLog::Log(stream.str(), LogType::INFO);
    
        // cleanup
        result = closesocket(sock);
        if (result == SOCKET_ERROR)
            throw SocketError(L"Closesocket", WSAGetLastError());
    
        result = WSACleanup();
        if (result == SOCKET_ERROR)
            throw SocketError(L"WSACleanup", WSAGetLastError());
    
        freeaddrinfo(pAddrInfo);
    
        DebugLog::Log(L"HttpGet() > Cleanup Successful ", LogType::INFO);
    
        return response;
    }
    
    wstring SocketError::ErrorMessage(const wstring & context, const int errorCode) const
    {
        wchar_t buf[1024];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, buf, sizeof(buf), 0);
        wchar_t * newLine = wcsrchr(buf, '\r');
        if (newLine) *newLine = '\0';
        wstringstream stream;
        stream << L"Socket error in " << context << L" (" << errorCode << L"): " << buf;
        return stream.str();
    }