Как вы делаете HTTP-запрос с C ++?

Есть ли способ легко сделать HTTP-запрос с C ++? В частности, я хочу загрузить содержимое страницы (API) и проверить содержимое, чтобы увидеть, содержит ли он 1 или 0. Возможно ли также загрузить содержимое в строку?

У меня такая же проблема. libcurl действительно завершен. Существует curl c ++-оболочки, который может вас заинтересовать, поскольку вы запрашиваете библиотеку C ++. neon – еще одна интересная библиотека C, которая также поддерживает webdav.

curlpp кажется естественным, если вы используете C ++. В дистрибутиве источника много примеров. Чтобы получить содержимое URL-адреса, вы делаете что-то подобное (извлеченное из примеров):

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

См. Каталог examples в дистрибутиве источника curlpp , существует множество более сложных случаев.

мои 2 цента ...

Код 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< 

Вот гораздо более эффективная реализация:

 #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); } в #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); } 

В Linux я попытался использовать cpp-netlib, libcurl, curlpp, urdl, boost :: asio и рассмотрел Qt (но отказался от лицензии). Все они были либо неполными для этого использования, имели неряшливые интерфейсы, имели плохую документацию, не были сохранены или не поддерживали https.

Затем, по предложению https://stackoverflow.com/a/1012577/278976 , я попробовал POCO. Вау, мне жаль, что я не видел это много лет назад. Ниже приведен пример запроса HTTP GET:

http://xjia.heroku.com/2011/09/10/learning-poco-get-with-http/

POCO является бесплатным, с открытым исходным кодом (расширенная лицензия). И нет, у меня нет какой-либо связи с компанией; Мне просто нравятся их интерфейсы. Отличные парни (и девушки).

http://pocoproject.org/download/index.html

Надеюсь, это поможет кому-то … мне потребовалось три дня, чтобы попробовать все эти библиотеки.

Существует более новая, менее зрелая обертка завитка, разработанная под названием C ++ Requests . Вот простой запрос 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; } 

Он поддерживает широкий спектр HTTP-глаголов и вариантов завивки. Здесь больше документации по использованию.

Отказ от ответственности: я являюсь хранителем этой библиотеки .

Поскольку вы хотите использовать C ++-решение, вы можете использовать Qt . Он имеет class QHttp, который вы можете использовать.

Вы можете проверить документы :

 http->setHost("qt.nokia.com"); http->get(QUrl::toPercentEncoding("/index.html")); 

Qt также имеет намного больше, что вы можете использовать в общем приложении C ++.

libCURL – довольно хороший вариант для вас. В зависимости от того, что вам нужно сделать, учебник должен рассказать вам, что вы хотите, в частности, для простого ручка. Но, в основном, вы могли бы это сделать, чтобы увидеть источник страницы:

 CURL* c; c = curl_easy_init(); curl_easy_setopt( c, CURL_URL, "www.google.com" ); curl_easy_perform( c ); curl_easy_cleanup( c ); 

Я верю, что это приведет к тому, что результат будет напечатан в стандартном режиме. Если вы хотите обработать его вместо этого – что, я полагаю, вы это сделаете – вам нужно установить CURL_WRITEFUNCTION. Все это описано в учебнике по скручиванию, приведенном выше.

Вот моя минимальная обертка вокруг cURL, чтобы иметь возможность просто извлекать веб-страницу в виде строки. Это полезно, например, для модульного тестирования. Это в основном shell RAII вокруг кода C.

Установите «libcurl» на свой компьютер yum install libcurl libcurl-devel или его эквивалент.

Пример использования:

 CURLplusplus client; string x = client.Get("http://google.com"); string y = client.Get("http://yahoo.com"); 

Реализация classа:

 #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(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; } }; 

С этим ответом я ссылаюсь на ответ от Software_Developer . Восстановив код, я обнаружил, что некоторые части устарели ( gethostbyname() ) или не обеспечивают обработку ошибок (создание сокетов, отправка чего-либо) для операции.

Следующий код Windows протестирован с 64-разрядной версией Visual Studio 2013 и Windows 8.1, а также с 64-разрядной версией Windows 7. Он будет нацелен на TCP-соединение IPv4 с веб-сервером http://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; } 

Рекомендации:

Отмена gethostbyname

Возвращаемое значение socket ()

Возвращаемое значение send ()

Вы можете проверить C ++ REST SDK (кодовое имя «Casablanca»). http://msdn.microsoft.com/en-us/library/jj950081.aspx

С помощью C ++ REST SDK вы можете более легко подключиться к HTTP-серверам из своего приложения на C ++.

Пример использования:

 #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"; } 

C ++ REST SDK - это проект Microsoft для облачной коммуникации клиент-сервер в собственном коде с использованием современного асинхронного дизайна C ++ API.

C ++ не предоставляет никакого способа сделать это напрямую. Это будет полностью зависеть от того, какие платформы и библиотеки у вас есть.

В худшем случае вы можете использовать библиотеку boost :: asio для установления TCP-соединения, отправки заголовков HTTP (RFC 2616) и непосредственного анализа ответов. Рассматривая потребности вашего приложения, это достаточно просто.

C и C ++ не имеют стандартной библиотеки для HTTP или даже для соединений сокетов. За эти годы были разработаны несколько портативных библиотек. Наиболее широко используемым, как говорили другие, является libcurl .

Ниже приведен список альтернатив libcurl (начиная с веб-сайта libcurl).

Кроме того, для Linux это простой HTTP-клиент. Вы можете реализовать свой простой HTTP-клиент GET, но это не сработает, если есть проверка подлинности или перенаправления, или если вам нужно работать за прокси. Для этих случаев вам нужна полномасштабная библиотека, такая как libcurl.

Для исходного кода с libcurl это самое близкое к тому, что вы хотите (Libcurl имеет много примеров ). Посмотрите на основную функцию. После успешного соединения содержимое html будет скопировано в буфер. Просто замените parseHtml на вашу собственную функцию.

Вы можете использовать библиотеку embeddedRest . Это легкая библиотека только для заголовков. Поэтому легко включить его в свой проект и не требует компиляции, потому что в нем нет файлов .cpp .

Пример запроса от readme.md из репо:

 #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 = "<

Вот некоторый (относительно) простой код C ++ 11, который использует libCURL для загрузки содержимого URL-адреса в std::vector :

http_download.hh

 # pragma once #include  #include  std::vector 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(contents); auto buffer = reinterpret_cast*>(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 download(string url, long* responseCode) { vector 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); } 

Обычно я бы рекомендовал нечто кросс-платформенное, например cURL, POCO или Qt. Однако вот пример Windows !:

 #include  #include  #include  // _bstr_t HRESULT hr; CComPtr request; hr = request.CoCreateInstance(CLSID_XMLHTTP60); hr = request->open( _bstr_t("GET"), _bstr_t("http://sofru.miximages.com/c%2B%2B/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(); 

Протокол HTTP очень прост, поэтому очень просто написать HTTP-клиент. Вот один

https://github.com/pedro-vicente/lib_netsockets

Он использует HTTP GET для извлечения файла с веб-сервера, а сервер и файл – это параметры командной строки. Удаленный файл сохраняется в локальной копии.

Отказ от ответственности: я автор

EDIT: отредактированный URL-адрес

Обратите внимание, что для этого не требуются libcurl, Windows.h или WinSock! Нет компиляции библиотек, конфигурации проекта и т. Д. У меня этот код работает в Visual Studio 2017 c ++ в 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(); 

Я просто понял, как это сделать, поскольку мне нужен простой скрипт доступа к API, библиотеки, подобные libcurl, вызывали у меня всевозможные проблемы (даже когда я следил за указаниями …), а WinSock слишком низкоуровневая и сложная ,

Я не совсем уверен в том, что все коды чтения IStream (в частности, условие – не стесняйтесь исправлять / улучшать), но эй, это работает , хлопот бесплатно! (Мне кажется, что, поскольку я использовал блокирующий (синхронный) вызов , это прекрасно, что bytesRead всегда будет> 0U, пока stream ( ISequentialStream ?) Не будет прочитан, но кто знает.)

См. Также: URL-адреса и ссылки на asynchronous подключаемый протокол

Хотя немного опоздал. Вы можете предпочесть https://github.com/Taymindis/backcurl .

Это позволяет вам делать HTTP-вызов на основе разработки мобильных c ++. Подходит для разработки мобильных игр

 bcl::init(); // init when using bcl::execute([&](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()->c_str()); printf("Sync === %s\n", ret.c_str()); }); bcl::cleanUp(); // clean up when no more using 

Вы можете использовать ACE для этого:

 #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; } 
  • Как использовать HttpWebRequest (.NET) асинхронно?
  • Как читать XML-ответ от URL-адреса в java?
  • Android: как анализировать URL-адрес String с пробелами для URI-объекта?
  • Как отправить запрос PUT / DELETE в jQuery?
  • Каков наилучший способ получить текущий URL в Spring MVC?
  • nodejs httprequest с данными - получение ошибки getaddrinfo ENOENT
  • Как создать asynchronous HTTP-запрос в JAVA?
  • Отправка HTTP-запросов с помощью VBA из Word
  • Как работает Request.IsAuthenticated?
  • Могу ли я каким-то образом выполнить синхронный HTTP-запрос через NSURLSession в Swift
  • Spring 3 MVC, доступ к HttpRequest от controllerа
  • Давайте будем гением компьютера.