¿Cómo hacer una solicitud HTTP con C++?

it-swarm.dev

¿Cómo hacer una solicitud HTTP con C++?

¿Hay alguna manera de hacer fácilmente una solicitud HTTP con C++? Específicamente, quiero descargar el contenido de una página (una API) y revisar el contenido para ver si contiene un 1 o un 0. ¿También es posible descargar el contenido en una cadena?
 223
Sam152
Yo tuve el mismo problema. libcurl es realmente completo. Hay un envoltorio de C++ curlpp que podría interesarle al solicitar una biblioteca de C++. neon es otra biblioteca de C interesante que también soporta WebDAV .
curlpp parece natural si usas C++. Hay muchos ejemplos proporcionados en la distribución de la fuente. Para obtener el contenido de una URL, debes hacer algo así (extraído de ejemplos):
// Edit : rewritten for cURLpp 0.7.3
// Note : namespace changed, was cURLpp in 0.7.2 ...

#include 
#include 

// RAII cleanup

curlpp::Cleanup myCleanup;

// Send request and get a result.
// Here I use a shortcut to get it in a string stream ...

std::ostringstream os;
os << curlpp::options::Url(std::string("http://www.wikipedia.org"));

string asAskedInQuestion = os.str();
Consulte el directorio examples en curlpp source distribution , hay muchos casos más complejos, así como un simple one minimal one using curlpp.
mis 2 centavos ...
 214
neuro
Código de Windows:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#pragma comment(lib,"ws2_32.lib")




int main( void ){

WSADATA wsaData;
SOCKET Socket;
SOCKADDR_IN SockAddr;
int lineCount=0;
int rowCount=0;
struct hostent *Host;
locale local;
char buffer[10000];
int i = 0 ;
int nDataLength;
string website_HTML;

// website url
string url = "www.google.com";

//HTTP GET
string 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 GET / HTTP
    send(Socket,get_http.c_str(), strlen(get_http.c_str()),0 );

    // recieve html
    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();

    // Display HTML source 
    cout<<website_HTML;

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


 return 0;
}
Aquí hay una implementación mucho mejor:
#include 
#include 
#include 

using std::string;

#pragma comment(lib,"ws2_32.lib")


HINSTANCE hInst;
WSADATA wsaData;
void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename);
SOCKET connectToServer(char *szServerName, Word portNum);
int getHeaderLength(char *content);
char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut);


int main()
{
    const int bufLen = 1024;
    char *szUrl = "http://stackoverflow.com";
    long fileSize;
    char *memBuffer, *headerBuffer;
    FILE *fp;

    memBuffer = headerBuffer = NULL;

    if ( WSAStartup(0x101, &wsaData) != 0)
        return -1;


    memBuffer = readUrl2(szUrl, fileSize, &headerBuffer);
    printf("returned from readUrl\n");
    printf("data returned:\n%s", memBuffer);
    if (fileSize != 0)
    {
        printf("Got some data\n");
        fp = fopen("downloaded.file", "wb");
        fwrite(memBuffer, 1, fileSize, fp);
        fclose(fp);
         delete(memBuffer);
        delete(headerBuffer);
    }

    WSACleanup();
    return 0;
}


void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename)
{
    string::size_type n;
    string url = mUrl;

    if (url.substr(0,7) == "http://")
        url.erase(0,7);

    if (url.substr(0,8) == "https://")
        url.erase(0,8);

    n = url.find('/');
    if (n != string::npos)
    {
        serverName = url.substr(0,n);
        filepath = url.substr(n);
        n = filepath.rfind('/');
        filename = filepath.substr(n+1);
    }

    else
    {
        serverName = url;
        filepath = "/";
        filename = "";
    }
}

SOCKET connectToServer(char *szServerName, Word portNum)
{
    struct hostent *hp;
    unsigned int addr;
    struct sockaddr_in server;
    SOCKET conn;

    conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (conn == INVALID_SOCKET)
        return NULL;

    if(inet_addr(szServerName)==INADDR_NONE)
    {
        hp=gethostbyname(szServerName);
    }
    else
    {
        addr=inet_addr(szServerName);
        hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
    }

    if(hp==NULL)
    {
        closesocket(conn);
        return NULL;
    }

    server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
    server.sin_family=AF_INET;
    server.sin_port=htons(portNum);
    if(connect(conn,(struct sockaddr*)&server,sizeof(server)))
    {
        closesocket(conn);
        return NULL;
    }
    return conn;
}

int getHeaderLength(char *content)
{
    const char *srchStr1 = "\r\n\r\n", *srchStr2 = "\n\r\n\r";
    char *findPos;
    int ofset = -1;

    findPos = strstr(content, srchStr1);
    if (findPos != NULL)
    {
        ofset = findPos - content;
        ofset += strlen(srchStr1);
    }

    else
    {
        findPos = strstr(content, srchStr2);
        if (findPos != NULL)
        {
            ofset = findPos - content;
            ofset += strlen(srchStr2);
        }
    }
    return ofset;
}

char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut)
{
    const int bufSize = 512;
    char readBuffer[bufSize], sendBuffer[bufSize], tmpBuffer[bufSize];
    char *tmpResult=NULL, *result;
    SOCKET conn;
    string server, filepath, filename;
    long totalBytesRead, thisReadSize, headerLen;

    mParseUrl(szUrl, server, filepath, filename);

    ///////////// step 1, connect //////////////////////
    conn = connectToServer((char*)server.c_str(), 80);

    ///////////// step 2, send GET request /////////////
    sprintf(tmpBuffer, "GET %s HTTP/1.0", filepath.c_str());
    strcpy(sendBuffer, tmpBuffer);
    strcat(sendBuffer, "\r\n");
    sprintf(tmpBuffer, "Host: %s", server.c_str());
    strcat(sendBuffer, tmpBuffer);
    strcat(sendBuffer, "\r\n");
    strcat(sendBuffer, "\r\n");
    send(conn, sendBuffer, strlen(sendBuffer), 0);

//    SetWindowText(edit3Hwnd, sendBuffer);
    printf("Buffer being sent:\n%s", sendBuffer);

    ///////////// step 3 - get received bytes ////////////////
    // Receive until the peer closes the connection
    totalBytesRead = 0;
    while(1)
    {
        memset(readBuffer, 0, bufSize);
        thisReadSize = recv (conn, readBuffer, bufSize, 0);

        if ( thisReadSize <= 0 )
            break;

        tmpResult = (char*)realloc(tmpResult, thisReadSize+totalBytesRead);

        memcpy(tmpResult+totalBytesRead, readBuffer, thisReadSize);
        totalBytesRead += thisReadSize;
    }

    headerLen = getHeaderLength(tmpResult);
    long contenLen = totalBytesRead-headerLen;
    result = new char[contenLen+1];
    memcpy(result, tmpResult+headerLen, contenLen);
    result[contenLen] = 0x0;
    char *myTmp;

    myTmp = new char[headerLen+1];
    strncpy(myTmp, tmpResult, headerLen);
    myTmp[headerLen] = NULL;
    delete(tmpResult);
    *headerOut = myTmp;

    bytesReturnedOut = contenLen;
    closesocket(conn);
    return(result);
}
 104
Software_Designer
En Linux, probé cpp-netlib, libcurl, curlpp, urdl, boost :: asio y consideré Qt (pero lo rechacé según la licencia). Todos estos estaban incompletos para este uso, tenían interfaces descuidadas, tenían poca documentación, no se mantenían o no eran compatibles con https.
Luego, a sugerencia de https://stackoverflow.com/a/1012577/278976 , probé POCO. Wow, desearía haber visto esto hace años. Aquí hay un ejemplo de cómo hacer una solicitud HTTP GET:
POCO es gratuito, de código abierto (impulsar licencia). Y no, no tengo ninguna afiliación con la empresa; Simplemente me gustan sus interfaces. Buen trabajo chicos (y chicas).
Espero que esto ayude a alguien ... me tomó tres días probar todas estas bibliotecas.
 35
Homer6
Se está desarrollando una envoltura de rizos más nueva y menos madura llamada Solicitudes de C++ . Aquí hay una simple solicitud GET:
#include 
#include 

int main(int argc, char** argv) {
    auto response = cpr::Get(cpr::Url{"http://httpbin.org/get"});
    std::cout << response.text << std::endl;
}
Admite una amplia variedad de verbos HTTP y opciones de enrollamiento. Hay más documentación de uso aquí .
Descargo de responsabilidad: soy el mantenedor de esta biblioteca .
 31
huu
Como desea una solución C++, puede usar Qt . Tiene una clase QHttp que puedes usar.
Puedes consultar el docs :
http->setHost("qt.nokia.com");
http->get(QUrl::toPercentEncoding("/index.html"));
Qt también tiene mucho más que podría usar en una aplicación común de C++.
 16
Marcelo Santos
libCURL es una buena opción para ti. Dependiendo de lo que necesites hacer, el tutorial debería decirte lo que quieres, específicamente para el manejo fácil. Pero, básicamente, puedes hacer esto solo para ver la fuente de una página:
CURL* c;
c = curl_easy_init();
curl_easy_setopt( c, CURL_URL, "www.google.com" );
curl_easy_perform( c );
curl_easy_cleanup( c );
Creo que esto hará que el resultado se imprima a la salida estándar. Si quiere manejarlo en su lugar, lo cual, supongo que sí, debe configurar el CURL_WRITEFUNCTION. Todo eso está cubierto en el tutorial de enrollamiento vinculado anteriormente.
 15
FreeMemory
Aquí está mi envoltorio mínimo alrededor de cURL para poder obtener una página web como una cadena. Esto es útil, por ejemplo, para pruebas unitarias. Es básicamente una envoltura RAII alrededor del código C.
Instale "libcurl" en su máquina yum install libcurl libcurl-devel o equivalente.
Ejemplo de uso:
CURLplusplus client;
string x = client.Get("http://google.com");
string y = client.Get("http://yahoo.com");
Implementación de la clase:
#include 


class CURLplusplus
{
private:
    CURL* curl;
    stringstream ss;
    long http_code;
public:
    CURLplusplus()
            : curl(curl_easy_init())
    , http_code(0)
    {

    }
    ~CURLplusplus()
    {
        if (curl) curl_easy_cleanup(curl);
    }
    std::string Get(const std::string& url)
    {
        CURLcode res;
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);

        ss.str("");
        http_code = 0;
        res = curl_easy_perform(curl);
        if (res != CURLE_OK)
        {
            throw std::runtime_error(curl_easy_strerror(res));
        }
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
        return ss.str();
    }
    long GetHttpCode()
    {
        return http_code;
    }
private:
    static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
    {
        return static_cast<CURLplusplus*>(userp)->Write(buffer,size,nmemb);
    }
    size_t Write(void *buffer, size_t size, size_t nmemb)
    {
        ss.write((const char*)buffer,size*nmemb);
        return size*nmemb;
    }
};
 15
Mark Lakata
Es posible que desee verificar C++ REST SDK (nombre en clave "Casablanca"). http://msdn.Microsoft.com/en-us/library/jj950081.aspx
Con el C++ REST SDK, puede conectarse más fácilmente a los servidores HTTP desde su aplicación C++.
Ejemplo de uso:
#include 
#include 

using namespace web::http;                  // Common HTTP functionality
using namespace web::http::client;          // HTTP client features

int main(int argc, char** argv) {
    http_client client("http://httpbin.org/");

    http_response response;
    // ordinary `get` request
    response = client.request(methods::GET, "/get").get();
    std::cout << response.extract_string().get() << "\n";

    // working with json
    response = client.request(methods::GET, "/get").get();
    std::cout << "url: " << response.extract_json().get()[U("url")] << "\n";
}
El C++ REST SDK es un proyecto de Microsoft para la comunicación cliente-servidor basado en la nube en código nativo utilizando un moderno diseño asíncrono de API de C++.
 11
copperoxide
Con esta respuesta me refiero a answer de Software_Developer . Al reconstruir el código, descubrí que algunas partes son obsoletas (gethostbyname()) o no proporcionan manejo de errores (creación de sockets, enviando algo) para una operación.
El siguiente código de Windows se prueba con Visual Studio 2013 y Windows 8.1 de 64 bits, así como con Windows 7 de 64 bits. Se dirigirá a una conexión IPv4 TCP con el servidor web de www.google.com.
#include 
#include 
#include 
#include 
#pragma comment(lib,"ws2_32.lib")
using namespace std;
    int main (){
    // Initialize Dependencies to the Windows Socket.
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
        cout << "WSAStartup failed.\n";
        system("pause");
        return -1;
    }

    // We first prepare some "hints" for the "getaddrinfo" function
    // to tell it, that we are looking for a IPv4 TCP Connection.
    struct addrinfo hints;
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;          // We are targeting IPv4
    hints.ai_protocol = IPPROTO_TCP;    // We are targeting TCP
    hints.ai_socktype = SOCK_STREAM;    // We are targeting TCP so its SOCK_STREAM

    // Aquiring of the IPv4 address of a Host using the newer
    // "getaddrinfo" function which outdated "gethostbyname".
    // It will search for IPv4 addresses using the TCP-Protocol.
    struct addrinfo* targetAdressInfo = NULL;
    DWORD getAddrRes = getaddrinfo("www.google.com", NULL, &hints, &targetAdressInfo);
    if (getAddrRes != 0 || targetAdressInfo == NULL)
    {
        cout << "Could not resolve the Host Name" << endl;
        system("pause");
        WSACleanup();
        return -1;
    }

    // Create the Socket Address Informations, using IPv4
    // We dont have to take care of sin_zero, it is only used to extend the length of SOCKADDR_IN to the size of SOCKADDR
    SOCKADDR_IN sockAddr;
    sockAddr.sin_addr = ((struct sockaddr_in*) targetAdressInfo->ai_addr)->sin_addr;    // The IPv4 Address from the Address Resolution Result
    sockAddr.sin_family = AF_INET;  // IPv4
    sockAddr.sin_port = htons(80);  // HTTP Port: 80

    // We have to free the Address-Information from getaddrinfo again
    freeaddrinfo(targetAdressInfo);

    // Creation of a socket for the communication with the Web Server,
    // using IPv4 and the TCP-Protocol
    SOCKET webSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (webSocket == INVALID_SOCKET)
    {
        cout << "Creation of the Socket Failed" << endl;
        system("pause");
        WSACleanup();
        return -1;
    }

    // Establishing a connection to the web Socket
    cout << "Connecting...\n";
    if(connect(webSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr)) != 0)
    {
        cout << "Could not connect";
        system("pause");
        closesocket(webSocket);
        WSACleanup();
        return -1;
    }
    cout << "Connected.\n";

    // Sending a HTTP-GET-Request to the Web Server
    const char* httpRequest = "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n";
    int sentBytes = send(webSocket, httpRequest, strlen(httpRequest),0);
    if (sentBytes < strlen(httpRequest) || sentBytes == SOCKET_ERROR)
    {
        cout << "Could not send the request to the Server" << endl;
        system("pause");
        closesocket(webSocket);
        WSACleanup();
        return -1;
    }

    // Receiving and Displaying an answer from the Web Server
    char buffer[10000];
    ZeroMemory(buffer, sizeof(buffer));
    int dataLen;
    while ((dataLen = recv(webSocket, buffer, sizeof(buffer), 0) > 0))
    {
        int i = 0;
        while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
            cout << buffer[i];
            i += 1;
        }
    }

    // Cleaning up Windows Socket Dependencies
    closesocket(webSocket);
    WSACleanup();

    system("pause");
    return 0;
}
Referencias:
 10
Vinz
C++ no proporciona ninguna forma de hacerlo directamente. Dependería completamente de qué plataformas y bibliotecas tengas.
En el peor de los casos, puede usar la biblioteca boost :: asio para establecer una conexión TCP, enviar los encabezados HTTP (RFC 2616) y analizar las respuestas directamente. En cuanto a las necesidades de su aplicación, esto es lo suficientemente simple de hacer.
 7
sybreon
Aquí hay un código que funcionará sin necesidad de usar ninguna biblioteca de terceros: Primero, defina su puerta de enlace, usuario, contraseña y cualquier otro parámetro que necesite enviar a este servidor específico.
#define USERNAME "user"
#define PASSWORD "your password"
#define GATEWAY "your gateway"
Aquí está el código en sí:
HINTERNET hOpenHandle, hResourceHandle, hConnectHandle;
const TCHAR* szHeaders = _T("Content-Type:application/json; charset=utf-8\r\n");


hOpenHandle = InternetOpen(_T("HTTPS"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hOpenHandle == NULL)
{
    return false;
}


hConnectHandle = InternetConnect(hOpenHandle,
    GATEWAY,
    INTERNET_DEFAULT_HTTPS_PORT,
    NULL, NULL, INTERNET_SERVICE_HTTP,
    0, 1);

if (hConnectHandle == NULL)
{
    InternetCloseHandle(hOpenHandle);
    return false;
}


hResourceHandle = HttpOpenRequest(hConnectHandle,
    _T("POST"),
    GATEWAY,
    NULL, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_KEEP_CONNECTION,
    1);

if (hResourceHandle == NULL)
{
    InternetCloseHandle(hOpenHandle);
    InternetCloseHandle(hConnectHandle);
    return false;
}

InternetSetOption(hResourceHandle, INTERNET_OPTION_USERNAME, (LPVOID)USERNAME, _tcslen(USERNAME));
InternetSetOption(hResourceHandle, INTERNET_OPTION_PASSWORD, (LPVOID)PASSWORD, _tcslen(PASSWORD));

std::string buf;
if (HttpSendRequest(hResourceHandle, szHeaders, 0, NULL, 0))
{
    while (true)
    {
        std::string part;
        DWORD size;
        if (!InternetQueryDataAvailable(hResourceHandle, &size, 0, 0))break;
        if (size == 0)break;
        part.resize(size);
        if (!InternetReadFile(hResourceHandle, &part[0], part.size(), &size))break;
        if (size == 0)break;
        part.resize(size);
        buf.append(part);
    }
}

if (!buf.empty())
{
    // Get data back
}

InternetCloseHandle(hResourceHandle);
InternetCloseHandle(hConnectHandle);
InternetCloseHandle(hOpenHandle);
Eso debería funcionar en un entorno de API Win32.
Aquí hay una ejemplo .
 3
Michael Haephrati
Puede usar embeddedRest library. Es una librería liviana de sólo encabezado. Así que es fácil incluirlo en su proyecto y no requiere compilación ya que no contiene archivos .cpp.
Solicite un ejemplo de readme.md de repo:
#include "UrlRequest.hpp"

//...

UrlRequest request;
request.Host("api.vk.com");
const auto countryId=1;
const auto count=1000;
request.uri("/method/database.getCities",{
    {"lang","ru"},
    {"country_id",countryId},
    {"count",count},
    {"need_all","1"},
});
request.addHeader("Content-Type: application/json");
auto response=std::move(request.perform());
if(response.statusCode()==200){
  cout<<"status code = "<<response.statusCode()<<", body = *"<<response.body()<<"*"<<endl;
}else{
  cout<<"status code = "<<response.statusCode()<<", description = "<<response.statusDescription()<<endl;
}
 3
fnc12
El protocolo HTTP es muy simple, por lo que es muy sencillo escribir un cliente HTTP. Aqui hay uno
Utiliza HTTP GET para recuperar un archivo de un servidor web, tanto el servidor como el archivo son parámetros de línea de comandos. El archivo remoto se guarda en una copia local.
Descargo de responsabilidad: yo soy el autor
EDITAR: URL editada
 3
Pedro Vicente
C y C++ no tienen una biblioteca estándar para HTTP o incluso para conexiones de socket. A lo largo de los años se han desarrollado algunas bibliotecas portátiles. El más utilizado, como han dicho otros, es libcurl .
Aquí hay una lista de alternativas a libcurl (que viene del sitio web de libcurl).
Además, para Linux, this es un cliente HTTP simple. Podría implementar su propio cliente HTTP GET simple, pero esto no funcionará si hay autenticación o redirecciones involucradas o si necesita trabajar detrás de un proxy. Para estos casos necesita una biblioteca completa como libcurl.
Para el código fuente con libcurl, este es el más cercano a lo que quieres (Libcurl tiene muchos ejemplos ). Mira la función principal. El contenido html se copiará en el búfer, después de una conexión exitosa. Simplemente reemplaza parseHtml con tu propia función.
 3
kgiannakakis
Aquí hay un código C++ 11 (relativamente) simple que utiliza libCURL para descargar el contenido de una URL en un std::vector<char>:

http_download.hh

# pragma once

#include 
#include 

std::vector<char> download(std::string url, long* responseCode = nullptr);

http_download.cc

#include "http_download.hh"

#include 
#include 
#include 

using namespace std;

size_t callback(void* contents, size_t size, size_t nmemb, void* user)
{
  auto chunk = reinterpret_cast<char*>(contents);
  auto buffer = reinterpret_cast<vector<char>*>(user);

  size_t priorSize = buffer->size();
  size_t sizeIncrease = size * nmemb;

  buffer->resize(priorSize + sizeIncrease);
  std::copy(chunk, chunk + sizeIncrease, buffer->data() + priorSize);

  return sizeIncrease;
}

vector<char> download(string url, long* responseCode)
{
  vector<char> data;

  curl_global_init(CURL_GLOBAL_ALL);
  CURL* handle = curl_easy_init();
  curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
  curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, callback);
  curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
  curl_easy_setopt(handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
  CURLcode result = curl_easy_perform(handle);
  if (responseCode != nullptr)
    curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, responseCode);
  curl_easy_cleanup(handle);
  curl_global_cleanup();

  if (result != CURLE_OK)
  {
    stringstream err;
    err << "Error downloading from URL \"" << url << "\": " << curl_easy_strerror(result);
    throw runtime_error(err.str());
  }

  return move(data);
}
 2
Drew Noakes
Tenga en cuenta que esto no requiere libcurl, Windows.h, o WinSock! No hay compilación de bibliotecas, no hay configuración de proyecto, etc. Tengo este código trabajando en Visual Studio 2017 c ++ en Windows 10:
#pragma comment(lib, "urlmon.lib")

#include 
#include 

using namespace std;

...

IStream* stream;
//Also works with https URL's - unsure about the extent of SSL support though.
HRESULT result = URLOpenBlockingStream(0, "http://google.com", &stream, 0, 0);
if (result != 0)
{
    return 1;
}
char buffer[100];
unsigned long bytesRead;
stringstream ss;
stream->Read(buffer, 100, &bytesRead);
while (bytesRead > 0U)
{
    ss.write(buffer, (long long)bytesRead);
    stream->Read(buffer, 100, &bytesRead);
}
stream.Release();
string resultString = ss.str();
Acabo de descubrir cómo hacerlo, ya que quería un simple script de acceso a la API, las bibliotecas como libcurl me estaban causando todo tipo de problemas (incluso cuando seguí las instrucciones ...), y WinSock es demasiado bajo y complicado. .
No estoy muy seguro de todo el IStream código de lectura (especialmente la condición while: siéntase libre de corregir/mejorar), pero hey, funciona , sin problemas! (Para mí tiene sentido que, dado que utilicé una llamada (bloqueo) , está bien, que bytesRead siempre será> 0U hasta que finalice la transmisión ( ISequentialStream ?) siendo leido, pero quien sabe.
 2
Andrew
En general, recomiendo algo multiplataforma como cURL, POCO o Qt. Sin embargo, aquí hay un ejemplo de Windows:
#include 
#include 
#include  // _bstr_t

HRESULT hr;
CComPtr<IXMLHTTPRequest> request;

hr = request.CoCreateInstance(CLSID_XMLHTTP60);
hr = request->open(
    _bstr_t("GET"),
    _bstr_t("https://www.google.com/images/srpr/logo11w.png"),
    _variant_t(VARIANT_FALSE),
    _variant_t(),
    _variant_t());
hr = request->send(_variant_t());

// get status - 200 if succuss
long status;
hr = request->get_status(&status);

// load image data (if url points to an image)
VARIANT responseVariant;
hr = request->get_responseStream(&responseVariant);
IStream* stream = (IStream*)responseVariant.punkVal;
CImage *image = new CImage();
image->Load(stream);
stream->Release();
 2
Peter Tseng
Aunque un poco tarde. Puede preferir https://github.com/Taymindis/backcurl .
Te permite hacer llamadas http en el desarrollo de c ++ móvil. Adecuado para el desarrollo de juegos móviles
bcl::init(); // init when using

bcl::execute<std::string>([&](bcl::Request *req) {
    bcl::setOpts(req, CURLOPT_URL , "http://www.google.com",
             CURLOPT_FOLLOWLOCATION, 1L,
             CURLOPT_WRITEFUNCTION, &bcl::writeContentCallback,
             CURLOPT_WRITEDATA, req->dataPtr,
             CURLOPT_USERAGENT, "libcurl-agent/1.0",
             CURLOPT_RANGE, "0-200000"
            );
}, [&](bcl::Response * resp) {
    std::string ret =  std::string(resp->getBody<std::string>()->c_str());
    printf("Sync === %s\n", ret.c_str());
});


bcl::cleanUp(); // clean up when no more using
 1
minika woon
Si está buscando una biblioteca de cliente HTTP en C++ que sea compatible con múltiples plataformas (Linux, Windows y Mac) para consumir servicios web Restful. Puedes tener las siguientes opciones.
  1. QT Network Library - Permite que la aplicación envíe solicitudes de red y reciba respuestas
  2. C++ REST SDK - Una biblioteca HTTP emergente de terceros con PPL compatibilidad
  3. Libcurl - Es probablemente una de las bibliotecas http más utilizadas en el mundo nativo.
 0
Surbhi Gupta
Puedes usar ACE para hacerlo:
#include "ace/SOCK_Connector.h"

int main(int argc, ACE_TCHAR* argv[])
{
    //HTTP Request Header
    char* szRequest = "GET /video/Nice.mp4 HTTP/1.1\r\nHost: example.com\r\n\r\n"; 
    int ilen = strlen(szRequest);

    //our buffer
    char output[16*1024];

    ACE_INET_Addr server (80, "example.com");
    ACE_SOCK_Stream peer;
    ACE_SOCK_Connector connector;
    int ires = connector.connect(peer, server);
    int sum = 0;
    peer.send(szRequest, ilen);
    while (true)
    {
        ACE_Time_Value timeout = ACE_Time_Value(15);
        int rc = peer.recv_n(output, 16*1024, &timeout);
        if (rc == -1)
        {
            break;
        }
        sum += rc;
    }
    peer.close();
    printf("Bytes transffered: %d",sum);

    return 0;
}
 0
inbaly

Content dated before 2011-04-08 (UTC) is licensed under CC BY-SA 2.5.Content dated from 2011-04-08 up to but not including 2018-05-02 (UTC) is licensed under CC BY-SA 3.0.Content dated on or after 2018-05-02 (UTC) is licensed under CC BY-SA 4.0. | Privacy
SHARE

Oscar perez

Arquitecto especialista en gestion de proyectos si necesitas desarrollar algun proyecto en Bogota contactame en el 3006825874 o visita mi pagina en www.arquitectobogota.tk

  • Image
  • Image
  • Image
  • Image
  • Image
    Blogger Comment
    Facebook Comment

0 comentarios:

Publicar un comentario