Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Помогите нубу сделать запрос C++

Помогите нубу сделать запрос C++

Поделиться
TirexiKПостоялецwww9 сен. 201718:27#0
Привет! В сетях нуб. Нужно послать запрос на сервер из десктопного windows приложения на С++, запрос вида https://thatserver.com/params:param1
И получить ответ.
Гуглом не смог найти рабочий пример, поставил boost/asio, прмеры только с http, меняю строчку запросу на свой, получаю bad request,  а затем вообще касперский забил тревогу и стал предлагать вылечить exeшник без с перезагрузкой компьютера.
На этом я понял глубину своей темности, подскажите по шагам, пожалуйста.

Update:
Плясал вокруг вот этого примера:

#include <boost/asio.hpp>
#include <iostream>

int main() {
  boost::asio::ip::tcp::iostream stream("httpbin.org", "http");
  stream << "GET /ip HTTP/1.1\r\nHost: httpbin.org\r\nConnection: closer\n\r\n";
  std::cout << stream.rdbuf();
}

Правка: 9 сен. 2017 18:32

Роман ШуваловУчастникwww10 сен. 201710:04#2
Во-первых, опечатка (в Connection не closer, а close).
Во-вторых, перед завершающими \n\r\n пропустил еще одну \r.
Во-вторых, допиши user-agent.
GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: TirexiK-client\r\nConnection: close\r\n\r\n

Это при условии, что пример вообще рабочий.

На будущее - открывай telnet, соединяйся с сервером по 80 порту и пиши все это там. Так ты отличишь заведомо запрос от рабочего кода.

TirexiKПостоялецwww10 сен. 201713:09#3
0iStalker
> http://cpp-netlib.org/

Не смог завести этого монстра, даже пустая функция main с подключенным заголовком #include <boost/network/protocol/http/client.hpp> не хочет компилироваться, вываливая тонны ошибок и предупреждений вида:

c:\sdk\cpp-netlib-0.12.0-final\boost\network\protocol\http\message\directives\status.hpp(31): error C2665: 'boost::variant<uint16_t,std::shared_future<uint16_t>,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_>::variant': none of the 3 overloads could convert all the argument types
1>  c:\sdk\boost_1_65_1\boost\variant\variant.hpp(1816): note: could be 'boost::variant<uint16_t,std::shared_future<uint16_t>,boost::detail::variant::void_,boost::detai...

Роман Шувалов
> Это при условии, что пример вообще рабочий.
Пример рабочий, но стоит в него вставить свой запрос - 400 Bad Request, в то время как тупо вставить строку запроса в браузер возвращается то что нужно в окне самого браузера.

boost::asio::ip::tcp::iostream stream("httpbin.org", "http");
stream << "GET /ip HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\n\r\n";

так работает.

А если у меня https? Как запросить вот это: https://api.nanopool.org/v1/zec/balance/address ?

Роман Шувалов
> Во-вторых, допиши user-agent.
Какой именно? Вписать такой же, как у хрома или эксплорера?

Правка: 10 сен. 2017 13:12

Роман ШуваловУчастникwww10 сен. 201713:45#4
TirexiK
> А если у меня https?
То всё значительно (update) немного сложней. Не знаю, как там с бустом, рекомендую попробовать curl (libcurl).

TirexiK
> > Во-вторых, допиши user-agent.
> Какой именно? Вписать такой же, как у хрома или эксплорера?
Лучше не копировать, а придумать свой. Я выше написал пример. Либо можно - и даже лучше - написать что-то вроде

Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)

Так выглядеит юзер-агент бота Яндекса.

Юзер-агент я вписывать настоятельно рекомендую, т.к. у меня без него некоторые сервера возвращали 400, в т.ч. сервер моего хостинга. А апач на localhost отдавал и без юзер-агента.

Правка: 10 сен. 2017 13:47

TirexiKПостоялецwww10 сен. 201716:10#5
До libcurl так и не добрался, нашёл пример с WinInet - всё работает :)

Если кому-то пригодится:

//нужно подключить библиотеку Wininet.lib в настройках проекта или через директиву pragma lib

#include <Windows.h>
#include <WinInet.h>
#include <string>
#include <iostream>

using namespace std;

// send https request
string SendHTTPSRequest_GET(const wstring& _server, const wstring& _page)
{
  char szData[1024];
  string recvStr;

  // initialize WinInet
  HINTERNET hInternet = InternetOpen(TEXT("WinInet Test"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
  if(hInternet != NULL)
  {
    // open HTTP session
    HINTERNET hConnect = InternetConnect(hInternet, _server.c_str(), INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1u);
    if(hConnect != NULL)
    {
      // open request
      HINTERNET hRequest = HttpOpenRequest(hConnect, L"GET", (LPCWSTR)_page.c_str(), NULL, NULL, 0, INTERNET_FLAG_SECURE, 1);
      if(hRequest != NULL)
      {
        // send request
        BOOL isSend = HttpSendRequest(hRequest, NULL, 0, NULL, 0);

        if(isSend)
        {
          for(;;)
          {
            // reading data
            DWORD dwByteRead;
            BOOL isRead = InternetReadFile(hRequest, szData, sizeof(szData) - 1, &dwByteRead);

            // break cycle if error or end
            if(isRead == FALSE || dwByteRead == 0) break;

            // saving result
            szData[dwByteRead] = 0;
            recvStr.append(szData, dwByteRead);
          }
        }

        // close request
        InternetCloseHandle(hRequest);
      }
      // close session
      InternetCloseHandle(hConnect);
    }
    // close WinInet
    InternetCloseHandle(hInternet);
  }  

  return recvStr;
}

//
int main(int argc, char *argv[])
{  
  string answer = SendHTTPSRequest_GET(L"httpbin.org", L"ip");
  
  cout << answer.c_str() << endl;

  system("PAUSE");
  return 0;
}

Роман ШуваловУчастникwww10 сен. 201716:19#6
TirexiK
> нашёл пример с WinInet - всё работает
Ок. Но на будущее рекомендую искать методы, работающие не только под виндой.
TirexiKПостоялецwww10 сен. 201716:22#7
Роман Шувалов
> Ок. Но на будущее рекомендую искать методы, работающие не только под виндой.

Учту, спасибо!

/ Форум / Программирование игр / Сеть

2001—2017 © GameDev.ru — Разработка игр