Для начала нам потребуется Curl – как инструмент для передачи данных в URL-синтаксисе, поддерживающий HTTP.
Установка библиотеки CURL
Вам необходимо скачать самые свежие исходники CURL и распаковать архив (для сборки .dll (win) или .so (liniux) файлов).
в зависимости от платформы скачайте нужные исходники
https://curl.haxx.se/download.html
Visual Studio 2015 сборка библиотеки Libcurl:
запускаем Visual Studio Command Line Tool
заходим в директорию winbuild скаченного и разархивированного исходника
запускаем команды
Set RTLIBCFG=static
затем
nmake /f Makefile.vc mode=static VC=14 MACHINE=x64 DEBUG=no // в случае сборки для 32 разрядных меняем х64 на x86 (если надо читаем BUILD.WINDOWS.txt)
в случае удачной сборки, получаем в новой директории ../builds/libcurl-vc14-x64-release-static-ipv6-sspi-winssl/lib
библиотеку libcurl_a.lib
интегрируем её в проект
1
Далее
во вкладке VC++ Directories
выбираем Library Directories и добавляем директорию где лежит libcurl_a.lib
во вкладке Configuration Properties –> Linker –> Input
выбираем Additional Dependencies добавляем сам фаил libcurl_a.lib
создаем .cpp
#include "stdafx.h" #include "httpWorker.h" //объявляем буфер, для хранения возможной ошибки, размер определяется в самой библиотеке static char errorBuffer[CURL_ERROR_SIZE]; //объялвяем буфер принимаемых данных static std::string buffer; //функция обратного вызова static int writer(char *data, size_t size, size_t nmemb, std::string *buffer) { //переменная - результат, по умолчанию нулевая int result = 0; //проверяем буфер if (buffer != NULL) { //добавляем к буферу строки из data, в количестве nmemb buffer->append(data, size * nmemb); //вычисляем объем принятых данных result = size * nmemb; } //вовзращаем результат return result; } httpWorker::httpWorker() { } httpWorker::httpWorker(const httpWorker& orig) { } httpWorker::~httpWorker() { } httpWorker::stiKKManswer httpWorker::iKKMtest(void){ stiKKManswer restul; // результат restul.resultCurl = 1; // если все хорошо std::stringstream _url; // ip адрес iKKM _url.clear(); std::stringstream _postfield; // заполняем POST запрос _postfield.clear(); _postfield << "key=" << iKKMconf.APIkey; // WEB API ключ if (iKKMpostfield.iSale != 0) _postfield << "&sale=" <<iKKMpostfield.iSale; // сумма чека if (iKKMpostfield.iCash != 0) _postfield << "&cash=" <<iKKMpostfield.iCash; // сколько дали наличности if (iKKMpostfield.iBank != 0) _postfield << "&bank=" << iKKMpostfield.iBank; // сколько оплатили банковской картой if (iKKMpostfield.iTara != 0) _postfield << "&tara=" <<iKKMpostfield.iTara; // не только тара, но и купоны и т.д if (iKKMpostfield.iCredit != 0) _postfield << "&credit=" << iKKMpostfield.iCredit; // кредитом if (iKKMpostfield.iTemdata != "") _postfield << "&itemdata=" << iKKMpostfield.iTemdata; //наименование товара или услуги для отправки в ОФД if (iKKMpostfield.iPrint != "") _postfield << "&print=" << iKKMpostfield.iPrint; // данные для печати на чеке std::string postfield = _postfield.str(); // формируем запрос CURL *curl; //объект типа CURL CURLcode res; //объект - результат вызова функции curl_easy_perform /* In windows, this will init the winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ curl = curl_easy_init(); //инициализация if(curl) { //проверяем _url << iKKMconf.httpAdr << iKKMconf.httpRes; // формируем ip adrress iKKM + в зависимости от запроса добавляем /api/ или /apicheck/ std::string url = _url.str(); // устанавливаем опцию, что будем работать по HTTP curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP); // задаем опцию - получить по IP адресу и Порту 8080 curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_PORT, iKKMconf.httpPort); buffer.clear(); // готовим буфер // устанавливаем опцию POST запроса curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postfield.c_str()); //указываем функцию обратного вызова для записи получаемых данных curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); //указываем куда записывать принимаемые данные curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); /* Check for errors */ if(res != CURLE_OK){ restul.resultCurl = -1; // Неудачно обратились iKKMconf.errorCodeDecr = "error IP iKKM"; }else{ // по этому адресу что-то есть начнем парсить long http_code = 0; int httpBodycode= 0; httpBodycode = atoi(buffer.c_str()); // str to int curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); if(http_code == 200){ // все удачно restul.resultCurl = 1; iKKMconf.errorCodeDecr = "no error"; if (httpBodycode >= 1){ iKKMconf.APIkey = httpBodycode; //получим WEB API для следующего запроса } } else // связь есть но ошибки на стороне iKKM restul.resultCurl = 0; restul.httpErrorCode = httpBodycode; iKKMconf.errorCodeDecr = erroCodeDecription(httpBodycode); // обработаем ошибки } /* always cleanup */ curl_easy_cleanup(curl); } curl_global_cleanup(); //выполняем обязательное завершение сессии buffer.clear(); return restul; } std::string httpWorker::erroCodeDecription(int icodeID){ switch(icodeID) { case 0: return "IP error"; case -1: return "Web-API-key error"; case -2: return "wait working"; case -3: return "error 24 hours, Z-report"; case -4: return "error 72 hours, block oofd.kz"; case -5: return "battery problem"; case -6: return "error Printer"; case -7: return "Parameter error"; default: std::stringstream _pfield; _pfield.clear(); _pfield << "error code [" << icodeID << "].Answer site help.ikkm.kz"; return _pfield.str(); } }
httpWorker.h
#ifndef HTTPWORKER_H #define HTTPWORKER_H #include "curl/curl.h" #include <sstream> #include <string> #include <stdlib.h> class httpWorker { public: httpWorker(); httpWorker(const httpWorker& orig); virtual ~httpWorker(); struct stiKKMconf{ std::string httpAdr; std::string httpRes; int httpPort; int APIkey; int printerLineLength; std::string facSerialNumber; std::string errorCodeDecr; stiKKMconf():errorCodeDecr("no error"),httpAdr("192.168.0.179"),httpRes("/api/"),httpPort(8080),APIkey(12345678), printerLineLength(24), facSerialNumber("555") { } }; struct stiKKMpostfield{ double iSale; int iCash; int iBank; int iTara; int iCredit; std::string iPrint; std::string iTemdata; stiKKMpostfield():iSale(0), iCash(0), iBank(0), iTara(0), iCredit(0), iPrint(""), iTemdata("") { } }; struct stiKKManswer{ int httpErrorCode; int resultCurl; stiKKManswer():httpErrorCode(-1), resultCurl(-1) { } }; stiKKMconf iKKMconf; stiKKMpostfield iKKMpostfield; stiKKManswer iKKMtest(void); private: std::string erroCodeDecription(int icodeID); }; #endif /* HTTPWORKER_H */