C как сделать get запрос
Перейти к содержимому

C как сделать get запрос

  • автор:

Сделать get запрос C++

Недавно начал изучать C++, моя цель на данный момент научиться работать с http запросами, но я попал в тупик, куда не посмотри, реализация http запросов уж очень закручена.

Составьте get запрос максимально просто. Получать ответ от страницы не нужно.

Пример ссылки для get-запроса

Ссылка скрыта от гостей

pp11

Green Team
16.09.2018 202 82

Копайте в сторону WinInet.
Ключевые слова: HINTERNET, InternetOpen, HttpSendRequest, HttpOpenRequest, InternetReadFile, WinApi.
В интернете куча готовых примеров, документаций и объяснений. Даже на русском языке.

centr

Green Team
31.01.2017 408 475

GitHub — libcpr/cpr: C++ Requests: Curl for People, a spiritual port of Python Requests.

C++ Requests: Curl for People, a spiritual port of Python Requests. — GitHub — libcpr/cpr: C++ Requests: Curl for People, a spiritual port of Python Requests.

#include int main(int argc, char** argv) < auto r = cpr::Get(cpr::Url, cpr::Authentication, cpr::Parameters, >); r.status_code; // 200 r.header["content-type"]; // application/json; charset=utf-8 r.text; // JSON text string >
#include #include int main(int argc, char** argv) < auto response = cpr::Get(cpr::Url); std::cout

GitHub - elnormous/HTTPRequest: Single-header C++ HTTP request class

Single-header C++ HTTP request class. Contribute to elnormous/HTTPRequest development by creating an account on GitHub.

#include "HTTPRequest.hpp" try < // you can pass http::InternetProtocol::V6 to Request to make an IPv6 request http::Request request("http://test.com/test"); // send a get request http::Response response = request.send("GET"); std::cout ); std::cout parameters = , >; response = request.send("POST", parameters, < "Content-Type: application/x-www-form-urlencoded" >); std::cout catch (const std::exception& e)

Ссылка скрыта от гостей

#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 
#include #include #include #include #include #include #include #include #include #include #include #include #include char http[]=; char host[]=; char parm[]=; std::string getProtocol( std::string url ) < std::string protocol = ""; int i = 0; for(i = 0; i < url.size(); i++) < if( url[i] != '/' || url[i+1] != '/' ) < protocol += url[i]; >else < protocol += "//"; break; >> return protocol; > std::string getHost( std::string url ) < std::string host = ""; url.replace(0, getProtocol(url).size(), ""); int i = 0; for(i = 0; i < url.size(); i++) < if( url[i] != '/' ) < host += url[i]; >else < break; >> return host; > std::string getAction( std::string url ) < std::string parm = ""; url.replace(0, getProtocol(url).size()+getHost(url).size(), ""); int i = 0; for(i = 0; i < url.size(); i++) < if( url[i] != '?' && url[i] != '#' ) < parm += url[i]; >else < break; >> return parm; > std::string getParams( std::vector < std::pair< std::string, std::string>> requestData ) < std::string parm = ""; std::vector< std::pair< std::string, std::string>>::iterator itr = requestData.begin(); for( ; itr != requestData.end(); ++itr ) < if( parm.size() < 1 ) < parm += ""; >else < parm += "&"; >parm += itr->first + "=" + itr->second; > return parm; > std::string GET( std::string url, std::vector < std::pair< std::string, std::string>> requestData ) < std::string http = getProtocol(url); std::string host = getHost(url); std::string script = getAction(url); std::string parm = getParams( requestData ); char buf[1024]; std::string header = ""; header += "GET "; header += http + host + script + "?" + parm; header += (std::string)" HTTP/1.1" + "\r\n"; header += (std::string)"Host: " + http + host + "/" + "\r\n"; header += (std::string)"User-Agent: Mozilla/5.0" + "\r\n"; //header += (std::string)"Accept: text/html" + "\r\n"; header += (std::string)"Accept-Language: ru,en-us;q=0.7,en;q=0.3" + "\r\n"; header += (std::string)"Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7" + "\r\n"; header += (std::string)"Connection: keep-alive " + "\r\n"; header += "\r\n"; int sock; struct sockaddr_in addr; struct hostent* raw_host; raw_host = gethostbyname( host.c_str() ); if (raw_host == NULL) < std::coutsock = socket(AF_INET, SOCK_STREAM, 0); addr.sin_family = AF_INET; addr.sin_port = htons(80); bcopy( (char*)raw_host->h_addr, (char*)&addr.sin_addr, raw_host->h_length ); if( connect( sock, (struct sockaddr *)&addr, sizeof(addr) ) < 0) < std::cerrchar * message = new char[ header.size() ]; for(int i = 0; i < header.size(); i++) < message[i] = header[i]; >send(sock, message, header.size(), 0); recv(sock, buf, sizeof(buf), 0); std::string answer = ""; for(int j = 0; j < 1024; j++) < answer += buf[j]; >return answer; >

Отправка GET/POST-запроса средствами чистого C++

Как реализовать простой GET/POST запрос без использования сторонних библиотек? Нашел много примеров, но там либо cpp-netlib, либо curl, а мне бы хотелось самому все это написать, но с сетью в С++ не работал, только через Qt. Было бы очень здорово увидеть маленький работающий пример 🙂

Отслеживать
30.9k 13 13 золотых знаков 96 96 серебряных знаков 157 157 бронзовых знаков
задан 25 дек 2015 в 22:28
851 1 1 золотой знак 8 8 серебряных знаков 19 19 бронзовых знаков

На чистом C++? Не смешите меня. Чистый C++ даже не имеет средств работы с консолью ( keypressed и т. п.), потому что «а вдруг программа будет писаться под систему, на которой нету клавиатуры», так что уж на доступ к сети без библиотек не надейтесь. Пользуйтесь boost::asio , и будет вам счастье.

25 дек 2015 в 22:43
я знаю, что можно это реализовать через winsocket
25 дек 2015 в 23:04
winsocket — это не чистый C++, это WinAPI (системная библиотека Windows).
25 дек 2015 в 23:10

Если даже socket API не доступно, то в баше достаточно специальное имя файла использовать /dev/tcp/$host/80

26 дек 2015 в 0:03

@VladD: как я уже явно упомянул это bash-специфично. Мне кажется, что просто POSIX не поддерживает это. Я не вижу упоминания Windows.

26 дек 2015 в 0:17

5 ответов 5

Сортировка: Сброс на вариант по умолчанию

Я решил проблему так:

#include #include #include #include #include #include #include #include #include #include #include #include #include char http[]=; char host[]=; char parm[]=; std::string getProtocol( std::string url ) < std::string protocol = ""; int i = 0; for(i = 0; i < url.size(); i++) < if( url[i] != '/' || url[i+1] != '/' ) < protocol += url[i]; >else < protocol += "//"; break; >> return protocol; > std::string getHost( std::string url ) < std::string host = ""; url.replace(0, getProtocol(url).size(), ""); int i = 0; for(i = 0; i < url.size(); i++) < if( url[i] != '/' ) < host += url[i]; >else < break; >> return host; > std::string getAction( std::string url ) < std::string parm = ""; url.replace(0, getProtocol(url).size()+getHost(url).size(), ""); int i = 0; for(i = 0; i < url.size(); i++) < if( url[i] != '?' && url[i] != '#' ) < parm += url[i]; >else < break; >> return parm; > std::string getParams( std::vector < std::pair< std::string, std::string>> requestData ) < std::string parm = ""; std::vector< std::pair< std::string, std::string>>::iterator itr = requestData.begin(); for( ; itr != requestData.end(); ++itr ) < if( parm.size() < 1 ) < parm += ""; >else < parm += "&"; >parm += itr->first + "=" + itr->second; > return parm; > std::string GET( std::string url, std::vector < std::pair< std::string, std::string>> requestData ) < std::string http = getProtocol(url); std::string host = getHost(url); std::string script = getAction(url); std::string parm = getParams( requestData ); char buf[1024]; std::string header = ""; header += "GET "; header += http + host + script + "?" + parm; header += (std::string)" HTTP/1.1" + "\r\n"; header += (std::string)"Host: " + http + host + "/" + "\r\n"; header += (std::string)"User-Agent: Mozilla/5.0" + "\r\n"; //header += (std::string)"Accept: text/html" + "\r\n"; header += (std::string)"Accept-Language: ru,en-us;q=0.7,en;q=0.3" + "\r\n"; header += (std::string)"Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7" + "\r\n"; header += (std::string)"Connection: keep-alive " + "\r\n"; header += "\r\n"; int sock; struct sockaddr_in addr; struct hostent* raw_host; raw_host = gethostbyname( host.c_str() ); if (raw_host == NULL) < std::coutsock = socket(AF_INET, SOCK_STREAM, 0); addr.sin_family = AF_INET; addr.sin_port = htons(80); bcopy( (char*)raw_host->h_addr, (char*)&addr.sin_addr, raw_host->h_length ); if( connect( sock, (struct sockaddr *)&addr, sizeof(addr) ) < 0) < std::cerrchar * message = new char[ header.size() ]; for(int i = 0; i < header.size(); i++) < message[i] = header[i]; >send(sock, message, header.size(), 0); recv(sock, buf, sizeof(buf), 0); std::string answer = ""; for(int j = 0; j < 1024; j++) < answer += buf[j]; >return answer; > 

Отслеживать
8,470 24 24 серебряных знака 37 37 бронзовых знаков
ответ дан 27 янв 2016 в 2:30
851 1 1 золотой знак 8 8 серебряных знаков 19 19 бронзовых знаков

Кто же строки по значению передает, это же растрата! Инициализация строк кавычками - тоже ужас. Игнорирование итераторов - фактическая замена C++ на "C с потоками". И до кучи, приведение типов в стиле C.

27 янв 2016 в 6:26
Я вам советую использовать boost.asio как показано в примере Abyx
27 янв 2016 в 16:32

std::string - замедляет работу, из-за работы с кучей. Лучше было бы использовать char* , а ваше header += заменить на wsprintf либо на strcat . Из концептуальных ошибок - 1. у вас константное число параметров header, а в реальности нужно переменное число, т.к. могут быть кукисы, авторизация, и много другого. 2. Не обработан ответ. Мусор в ответе. Но. думаю пример сгодится, как для начинающего.

26 июн 2019 в 6:47

На "чистом C++" много чего нельзя сделать, потому что стандартная библиотека языка слишком миниатюрная, она не включает достаточно функционала, чтобы работать с HTTP.

В какой-то мере "полустандартной" библиотекой является boost (какие-то его библиотеки позже становятся частью стандартной библиотеки), поэтому можно воспользоваться boost::asio. Однако учтите, что это всё равно достаточно низкоуровневая библиотека. Простой HTTP-запрос вы сможете написать в пару строчек, но вы будете вручную разруливать все сотни современных возможностей HTTP: безопасное соединение, сжатие траффика, кэширование и так далее и тому подобное. Я уж молчу про новую версию стандарта. И если вы можете сказать серверу "я не поддерживаю сжатие, давай данные как есть", то проигнорировать HTTPS вы ну никак не сможете.

Вы изобретёте велосипед, который никому не будет нужен. Вы станете лучше понимать потроха HTTP, конечно, но кроме как для обучения смысла писать такой код нет.

Если вам нужны маленькие и работающие примеры, то посмотрите Debunking Stroustrup's debunking of the myth “C++ is for large, complicated, programs only” — они там есть на всех языках, в том числе несколько на C++, а один из примеров написан самим Страуструпом.

Отправить GET запрос через сокет

Думаю что в конце с recv что-то не так, там нужно или цикл делать и читать длину Content-Length: в хедере или что-то другое, не понимаю.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
/* ClientTCP */ #include #include //printf #include //strlen #include //socket #include //inet_addr #include // for open #include // for close #include #include int main(int argc , char **argv) { int sockfd, port; char *enteredString;//enter in console enteredString = malloc(sizeof(char)); char hostname[256]; //string ip oder domain char path[256];// domain/pfad struct hostent *he; int p1, p2; struct sockaddr_in server; if (argc  2) { printf("usage: http://www.example.com/path\n"); exit(1); } enteredString = argv[1]; /***************START URL routine*******************/ int count = 0; for (int i = 0; i  strlen(enteredString); i++) { if (enteredString[i] == '/') { count++; if (count == 2) { p1 = i+1;// } else if (count == 3) { p2 = i;// break; } } //-1 da i bei 0 anfaengt if (i == strlen(enteredString)-1 && count  3) {// printf("Please enter URL in this format: http://www.example.com/path\n"); exit(1); } } strncpy(hostname, enteredString + p1, p2-p1); strncpy(path, enteredString + p2, strlen(enteredString)-p2); //hostname[p2-p1] = '\0';//add null terminator to end of hostname //path[strlen(enteredString)-p2] = '\0';//add null terminator to end of path /***************END URL routine*******************/ port = 80; if ((he = gethostbyname(hostname)) == NULL) { //Get an IP address for a hostname //gethostbyname failed herror("gethostbyname"); return 1; } //Create socket sockfd = socket(AF_INET , SOCK_STREAM , 0);//IPv4, STREAM NOT DDGRAM, TCP if (sockfd  0) { printf("Could not create socket\n"); } printf("Socket created\n"); server.sin_family = AF_INET; //IPv4 /* copy the network address to sockaddr_in structure */ memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);//where, what, len server.sin_port = htons(port);//Host-to-network-short 16 bit. convert port to Network Byte Order (Big-Endian ) //Connect to remote server if (connect(sockfd , (struct sockaddr *)&server , sizeof(server))  0) { perror("connect failed. Error"); return 1; } char request[256];//Send this message to server char server_reply[10000];//buffer for server reply /* GET /ip HTTP/1.1\r\n HOST: httpbin.org\r\n \r\n */ sprintf(request, "%s %s %s%s %s%s", "GET", path, "HTTP/1.1\r\n", "HOST:", hostname, "\r\n\r\n"); //Send some data with TCP if(send(sockfd, request, strlen(request), 0)  0) { printf("Send failed\n"); exit(1); } printf("Request sended\n"); if(recv(sockfd, server_reply , sizeof(server_reply), 0)  0) {//receive answer printf("recv failed\n"); } /* char *data = strstr(server_reply, "\r\n\r\n");//save data after header data+=4;*/ Тут читать только данные без http header printf("Server reply: \n\n%s\n", server_reply);//print the answer close(sockfd); return 0; }

проблема еще в том что без http хедера я всегда получают 4 символа вместо бинарного кода картинки.

Добавлено через 14 минут
Если в конец изменить на:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
while(1) { //Send some data with TCP if(send(sockfd, request, strlen(request), 0)  0) { printf("Send failed\n"); exit(1); } //Receive a reply from the server if( recv(sockfd , server_reply , 2000 , 0)  0) { puts("recv failed"); break; } puts("Server reply :"); puts(server_reply); } close(sockfd);

C curl¶

Пример GET запроса с сайта http://example.com, ответ приходит в формате HTML.

#include #include  int main(void)  CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl)  curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); /* example.com is redirected, so we tell libcurl to follow redirection */ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* Check for errors */ if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); /* always cleanup */ curl_easy_cleanup(curl); > return 0; >

Результат выполнения программы ¶

 html> head> title>Example Domaintitle> meta charset="utf-8" /> meta http-equiv="Content-type" content="text/html; charset=utf-8" /> meta name="viewport" content="width=device-width, initial-scale=1" /> style type="text/css"> body  background-color: #f0f0f2; margin: 0; padding: 0; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; > div  width: 600px; margin: 5em auto; padding: 50px; background-color: #fff; border-radius: 1em; > a:link, a:visited  color: #38488f; text-decoration: none; > @media (max-width: 700px)  body  background-color: #fff; > div  width: auto; margin: 0 auto; border-radius: 0; padding: 1em; > > style> head> body> div> h1>Example Domainh1> p>This domain is established to be used for illustrative examples in documents. You may use this domain in examples without prior coordination or asking for permission.p> p>a href="http://www.iana.org/domains/example">More information. a>p> div> body> html>

wttr.in¶

http://wttr.in - веб сервис для получения информации о погоде, ориентированный на отображение в консоле

Пример GET запроса с сайта http://wttr.in, ответ приходит сплошным текстом, если в заголовках запроса User-Agent указан curl .

Тот же результат можно получить выполнив в консоле:

$ curl http://wttr.in/Pyshma
#include #include  int main(void)  CURL *curl; CURLcode res; curl = curl_easy_init(); if(curl)  curl_easy_setopt(curl, CURLOPT_URL, "http://wttr.in/Pyshma"); curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.47.1"); /* example.com is redirected, so we tell libcurl to follow redirection */ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* Check for errors */ if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); /* always cleanup */ curl_easy_cleanup(curl); > return 0; >

Вывод погоды с сайта http://wttr.in/ ¶

$ ./weather Weather for City: Pyshma, Russia Freezing fog _ - _ - _ - -4 °C _ - _ - _ ← 2 km/h _ - _ - _ - 0 km 0.0 mm ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Thu 10. Mar ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ Mist │ Mist │ Freezing fog │ Freezing fog │ │ _ - _ - _ - -6 °C │ _ - _ - _ - -8 – -7 °C │ _ - _ - _ - -6 – -4 °C │ _ - _ - _ - -9 °C │ │ _ - _ - _ ← 3 km/h │ _ - _ - _ ← 2 km/h │ _ - _ - _ ↖ 4 – 5 km/h │ _ - _ - _ ↑ 7 – 11 km/h │ │ _ - _ - _ - 2 km │ _ - _ - _ - 2 km │ _ - _ - _ - 0 km │ _ - _ - _ - 0 km │ │ 0.0 mm | 0% │ 0.0 mm | 0% │ 0.0 mm | 0% │ 0.1 mm | 72% │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Fri 11. Mar ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ Freezing fog │ Freezing fog │ _`/"".-. Light snow │ Freezing fog │ │ _ - _ - _ - -17 – -13 °C │ _ - _ - _ - -7 – -3 °C │ ,\_( ). -7 – -4 °C │ _ - _ - _ - -14 – -10 °C │ │ _ - _ - _ ↑ 8 – 9 km/h │ _ - _ - _ ↑ 8 – 9 km/h │ /(___(__) ↑ 8 – 12 km/h │ _ - _ - _ ↗ 9 – 14 km/h │ │ _ - _ - _ - 0 km │ _ - _ - _ - 0 km │ * * * 10 km │ _ - _ - _ - 0 km │ │ 0.0 mm | 0% │ 0.0 mm | 0% │ * * * 0.0 mm | 0% │ 0.0 mm | 0% │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Sat 12. Mar ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ _`/"".-. Light snow │ .-. Moderate snow │ .-. Moderate snow │ .-. Moderate snow │ │ ,\_( ). -16 – -12 °C │ ( ). -8 – -4 °C │ ( ). -6 – -4 °C │ ( ). -10 °C │ │ /(___(__) → 9 – 10 km/h │ (___(__) → 9 – 12 km/h │ (___(__) ↗ 6 – 9 km/h │ (___(__) ↘ 6 – 11 km/h │ │ * * * 10 km │ * * * * 5 km │ * * * * 5 km │ * * * * 5 km │ │ * * * 0.1 mm | 4% │ * * * * 0.2 mm | 14% │ * * * * 0.1 mm | 52% │ * * * * 0.2 mm | 52% │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ Check new Feature: wttr.in/Moon or wttr.in/Moon@2016-Mar-23 to see the phase of the Moon Follow @igor_chubin for wttr.in updates

qrenco.de¶

http://qrenco.de - веб сервис для получения QR-кодов в текстовом виде

В качестве самостоятельной работы предлагаю вам написать программу которая принимает на вход текст, а на выходе показывает QR-код в текстовом виде.

Генерация QR-кода ¶

$ ./qrcode "Купи хлеба!" █████████████████████████████████ █████████████████████████████████ ████ ▄▄▄▄▄ █▀█ █▄█▄▄ █ ▄▄▄▄▄ ████ ████ █ █ █▀▀▀█ █ ▀█ █ █ ████ ████ █▄▄▄█ █▀ █▀▀█▄███ █▄▄▄█ ████ ████▄▄▄▄▄▄▄█▄▀ ▀▄█▄▀▄█▄▄▄▄▄▄▄████ ████▄▄▄▄ ▀▄▄ ▄▀▄▀▄█ ▀ ▀ █ ▀████ ████ ▄▀ ▄▀██▄█▀█▀▀ ▀ ██▀▀▄█████ ████ ▀▀█▄▀▄▀▄ ▄█▄▀█▄▄█▀█▄ █▀▀████ ████ █▄ ██▄ █ ▄ ▄▄█▀█ █▀█ █▀████ ████▄██▄▄█▄█ ▄▄▄▀▀█▄ ▄▄▄ ▀█▀ ████ ████ ▄▄▄▄▄ █▄▄▀█▀ ▄▄ █▄█ ▀ ▀████ ████ █ █ █ ▀██▄█▄█ ▄ █ ████ ████ █▄▄▄█ █ ▀▀ ▄█▀▄ ▄ █▄█ █ ████ ████▄▄▄▄▄▄▄█▄█▄▄███▄▄█▄████▄▄████ █████████████████████████████████ █████████████████████████████████

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *