সি ++ দিয়ে সহজেই কোনও HTTP অনুরোধ করার কোনও উপায় আছে কি? বিশেষত, আমি কোনও পৃষ্ঠার সামগ্রী (একটি এপিআই) ডাউনলোড করতে চাইছি এবং এতে 1 বা একটি 0 রয়েছে কিনা তা দেখতে সামগ্রীগুলি পরীক্ষা করতে চাই? বিষয়বস্তুগুলি স্ট্রিংয়ে ডাউনলোড করাও কি সম্ভব?
সি ++ দিয়ে সহজেই কোনও HTTP অনুরোধ করার কোনও উপায় আছে কি? বিশেষত, আমি কোনও পৃষ্ঠার সামগ্রী (একটি এপিআই) ডাউনলোড করতে চাইছি এবং এতে 1 বা একটি 0 রয়েছে কিনা তা দেখতে সামগ্রীগুলি পরীক্ষা করতে চাই? বিষয়বস্তুগুলি স্ট্রিংয়ে ডাউনলোড করাও কি সম্ভব?
উত্তর:
আমারও একই সমস্যা ছিল। libcurl সত্যিই সম্পূর্ণ। একটি সি ++ র্যাপার কার্ল্প রয়েছে যা আপনি সি ++ লাইব্রেরির জন্য জিজ্ঞাসা করার সাথে সাথে আপনার আগ্রহী হতে পারে। নিয়ন হ'ল আরও একটি আকর্ষণীয় সি লাইব্রেরি যা ওয়েবডিএভি সমর্থন করে ।
আপনি সি ++ ব্যবহার করলে কার্ল্প স্বাভাবিক মনে হয়। উত্স বিতরণে সরবরাহ করা অনেকগুলি উদাহরণ রয়েছে। কোনও ইউআরএল এর সামগ্রী পেতে আপনি এর মতো কিছু করেন (উদাহরণগুলি থেকে বের করা):
// Edit : rewritten for cURLpp 0.7.3
// Note : namespace changed, was cURLpp in 0.7.2 ...
#include <curlpp/cURLpp.hpp>
#include <curlpp/Options.hpp>
// 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
ডিরেক্টরিটি দেখুন , আরও অনেক জটিল কেস রয়েছে, পাশাপাশি কার্লপ ব্যবহার করে একটি সাধারণ সম্পূর্ণ ন্যূনতম একটি রয়েছে।
আমার 2 সেন্ট ...
os << myRequest.perform();
সঙ্গে myRequest.setOpt( new curlpp::options::WriteStream( &os ) ); myRequest.perform();
দিলেন ফলাফল নেই। ব্যবহার না করার বিষয়টি নিশ্চিত করুন http://example.com
, এটি একটি খালি পৃষ্ঠা ফিরে আসবে। আরও ভাল ব্যবহার যেমন http://www.wikipedia.org
।
উইন্ডোজ কোড:
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <locale>
#include <sstream>
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;
}
এখানে আরও কার্যকর বাস্তবায়ন:
#include <windows.h>
#include <string>
#include <stdio.h>
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);
}
GET / HTTP/1.1.1/... etc
কী করেছেন? আমি কী প্রেরণ করব তা কীভাবে বিন্যাস করতে পারি?
আপডেট 2020: আমার কাছে একটি নতুন উত্তর রয়েছে যা এটি প্রতিস্থাপন করে, এখন 8 বছর বয়সী, এক: https://stackoverflow.com/a/61177330/278976
লিনাক্সে, আমি সিপিপি-নেটলিব, লাইবকার্লল, কার্লপ, ইউআরডিএল, বুস্ট :: এশিয়াও এবং কিউটি হিসাবে বিবেচনা করেছি (তবে এটি লাইসেন্সের ভিত্তিতে পরিণত হয়েছে)। এগুলি সমস্তই এই ব্যবহারের জন্য অসম্পূর্ণ ছিল, opালু ইন্টারফেস ছিল, দুর্বল ডকুমেন্টেশন ছিল, অবিশ্বাস্য ছিল বা https সমর্থন করে না।
তারপরে, https://stackoverflow.com/a/1012577/278976 এর পরামর্শে আমি POCO চেষ্টা করেছি। বাহ, আমি আশা করি আমি এই বছর আগে দেখেছি। এখানে পোকোর সাথে একটি এইচটিটিপি জিইটি অনুরোধ করার উদাহরণ রয়েছে:
https://stackoverflow.com/a/26026828/2817595
পোকো ফ্রি, ওপেন সোর্স (লাইসেন্স বাড়ানো)। এবং না, সংস্থার সাথে আমার কোনও সম্পর্ক নেই; আমি ঠিক তাদের ইন্টারফেস পছন্দ করি। দারুণ কাজের ছেলেরা (এবং গাল)।
https://pocoproject.org/download.html
আশা করি এটি কাউকে সাহায্য করবে ... এই সমস্ত লাইব্রেরি চেষ্টা করে দেখতে আমার তিন দিন সময় লেগেছে।
একটি নতুন, কম পরিপক্ক কার্ল র্যাপার তৈরি করা হচ্ছে যা C ++ অনুরোধগুলি নামে পরিচিত । এখানে একটি সাধারণ জিইটি অনুরোধ রইল:
#include <iostream>
#include <cpr.h>
int main(int argc, char** argv) {
auto response = cpr::Get(cpr::Url{"http://httpbin.org/get"});
std::cout << response.text << std::endl;
}
এটি বিভিন্ন ধরণের HTTP ক্রিয়া এবং কার্ল বিকল্পগুলিকে সমর্থন করে। এখানে আরও ব্যবহারের ডকুমেন্টেশন রয়েছে ।
দাবি অস্বীকার: আমি এই গ্রন্থাগারের রক্ষণাবেক্ষণকারী ।
কেবলমাত্র একটি স্ট্রিং হিসাবে একটি ওয়েবপৃষ্ঠা আনতে সক্ষম হতে সিআরএল-এর চারপাশে আমার ন্যূনতম র্যাপার। এটি দরকারী, উদাহরণস্বরূপ, ইউনিট পরীক্ষার জন্য। এটি মূলত সি কোডের চারপাশে একটি RAII মোড়ক।
আপনার মেশিনে yum install libcurl libcurl-devel
বা সমতুল্যে "libcurl" ইনস্টল করুন ।
ব্যবহারের উদাহরণ:
CURLplusplus client;
string x = client.Get("http://google.com");
string y = client.Get("http://yahoo.com");
শ্রেণি বাস্তবায়ন:
#include <curl/curl.h>
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;
}
};
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 সেট করা দরকার। এর সবগুলি উপরে লিঙ্কযুক্ত কার্ল টিউটোরিয়ালে আচ্ছাদিত।
আপনি যেমন একটি সি ++ সমাধান চান, আপনি Qt ব্যবহার করতে পারেন । এটিতে আপনি কিউএইচটিপি ক্লাস ব্যবহার করতে পারেন।
আপনি দস্তাবেজগুলি পরীক্ষা করতে পারেন :
http->setHost("qt.nokia.com");
http->get(QUrl::toPercentEncoding("/index.html"));
Qt এর আরও অনেক কিছুই রয়েছে যা আপনি একটি সাধারণ সি ++ অ্যাপ্লিকেশনটিতে ব্যবহার করতে পারেন।
QNetworkAccessManager
4.4 Qt থেকে নথিভুক্ত করা হয়েছে; এবং Qt 4.8 এ বলেছেন: QHttp - This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.
সুতরাং আমি অনুমান করি যে এটি অবজ্ঞাত সতর্কতাগুলিকে উপেক্ষা করলে এটি এখনও উপলব্ধ।
আপনি সি ++ রিস্ট এসডিকে (কোডনাম "ক্যাসাব্লাঙ্কা") চেক করতে চাইতে পারেন ।http://msdn.microsoft.com/en-us/library/jj950081.aspx
C ++ REST SDK এর সাহায্যে আপনি আপনার সি ++ অ্যাপ্লিকেশন থেকে আরও সহজেই এইচটিটিপি সার্ভারের সাথে সংযোগ করতে পারবেন।
ব্যবহারের উদাহরণ:
#include <iostream>
#include <cpprest/http_client.h>
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";
}
সি ++ আরএসটি এসডিকে একটি আধুনিক অ্যাসিনক্রোনাস সি ++ এপিআই ডিজাইন ব্যবহার করে নেটিভ কোডে ক্লাউড-ভিত্তিক ক্লায়েন্ট-সার্ভার যোগাযোগের জন্য একটি মাইক্রোসফ্ট প্রকল্প।
এই উত্তরটির সাথে আমি সফ্টওয়্যার_ ডেভেলপারের উত্তরটি উল্লেখ করব । কোডটি পুনর্নির্মাণের মাধ্যমে আমি দেখতে পেয়েছি যে কিছু অংশ অবমূল্যায়ন করা হয়েছে ( gethostbyname()
) বা ত্রুটি পরিচালনার ব্যবস্থা করে না কোনও অপারেশনের জন্য (সকেট তৈরি, কিছু প্রেরণ) সরবরাহ করে না।
নিম্নলিখিত উইন্ডোজ কোডটি ভিজ্যুয়াল স্টুডিও 2013 এবং উইন্ডোজ 8.1 64-বিটের পাশাপাশি উইন্ডোজ 7 64-বিটের সাথে পরীক্ষিত হয়। এটি www.google.com এর ওয়েব সার্ভারের সাথে একটি আইপিভি 4 টিসিপি সংযোগকে লক্ষ্য করবে।
#include <winsock2.h>
#include <WS2tcpip.h>
#include <windows.h>
#include <iostream>
#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;
}
তথ্যসূত্র:
সি ++ সরাসরি এটি করার কোনও উপায় সরবরাহ করে না। আপনার কাছে কী প্ল্যাটফর্ম এবং লাইব্রেরি রয়েছে তা সম্পূর্ণরূপে নির্ভর করবে।
সবচেয়ে খারাপ ক্ষেত্রে, আপনি একটি টিসিপি সংযোগ স্থাপন করতে, HTTP শিরোনাম (আরএফসি 2616) প্রেরণ করতে এবং সরাসরি প্রতিক্রিয়াগুলি পার্স করার জন্য বুস্ট :: এশিয়া লাইব্রেরিটি ব্যবহার করতে পারেন। আপনার অ্যাপ্লিকেশন প্রয়োজনীয়তার দিকে তাকানো, এটি করা সহজ।
এখানে এমন কিছু কোড রয়েছে যা কোনও তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করার প্রয়োজন ছাড়াই কাজ করবে: প্রথমে আপনার গেটওয়ে, ব্যবহারকারী, পাসওয়ার্ড এবং আপনাকে এই নির্দিষ্ট সার্ভারে প্রেরণের জন্য প্রয়োজনীয় যে কোনও প্যারামিটার সংজ্ঞায়িত করুন।
#define USERNAME "user"
#define PASSWORD "your password"
#define GATEWAY "your gateway"
এখানে কোডটি নিজেই:
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);
এটি একটি Win32 এপিআই পরিবেশে কাজ করা উচিত।
এখানে একটি উদাহরণ ।
InternetConnect
পূর্ণ ইউআরএল দেওয়া হলে নাল ফেরায়, তবে কেবলমাত্র ডোমেন নাম সরবরাহ করা হলে নন-নাল মান প্রদান করে। সুতরাং যে পৃষ্ঠাটি আমি ডাউনলোড করতে চাই তা পেতে আমি কখন / কোথায় পূর্ণ ইউআরএল ব্যবহার করব?
সি এবং সি ++ এর কাছে এইচটিটিপি বা এমনকি সকেট সংযোগের জন্য স্ট্যান্ডার্ড লাইব্রেরি নেই। বছরের পর বছর ধরে কিছু পোর্টেবল লাইব্রেরি তৈরি করা হয়েছে। সর্বাধিক ব্যবহৃত হয়, যেমন অন্যরা বলেছে, হ'ল লাইবকার্ল ।
এখানে একটি তালিকা libcurl (libcurl এর ওয়েবসাইট থেকে আসা) বিকল্পগুলির রয়েছে।
লিনাক্সের জন্যও এটি একটি সহজ HTTP- র ক্লায়েন্ট। আপনি আপনার নিজের সাধারণ এইচটিটিপি জিইটি ক্লায়েন্টকে বাস্তবায়ন করতে পারেন, তবে এতে যদি প্রমাণীকরণ বা পুনর্নির্দেশ জড়িত থাকে বা যদি আপনাকে প্রক্সিটির পিছনে কাজ করার প্রয়োজন হয় তবে এটি কাজ করবে না। এই ক্ষেত্রে আপনার libcurl এর মতো একটি পূর্ণ বিকাশযুক্ত গ্রন্থাগার প্রয়োজন।
Libcurl সহ উত্স কোডের জন্য, এটি আপনি যা চান তার নিকটতম (Libcurl এর অনেক উদাহরণ রয়েছে )। মূল ফাংশনটি দেখুন। এইচটিএমএল সামগ্রীটি সফলভাবে সংযোগের পরে বাফারে অনুলিপি করা হবে। আপনার নিজস্ব ফাংশনটির সাথে কেবল পার্সএইচটিএমএল প্রতিস্থাপন করুন।
আপনি এম্বেডড্রেষ্ট লাইব্রেরি ব্যবহার করতে পারেন । এটি কেবলমাত্র হালকা হেডার লাইব্রেরি। সুতরাং এটি আপনার প্রকল্পের সাথে অন্তর্ভুক্ত করা সহজ এবং এতে কোনও .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 = "<<response.statusCode()<<", body = *"<<response.body()<<"*"<<endl;
}else{
cout<<"status code = "<<response.statusCode()<<", description = "<<response.statusDescription()<<endl;
}
netdb.h
তাই আমি কিছুটা সাহায্য চাই
এইচটিটিপি প্রোটোকলটি খুব সহজ, এইচটিটিপি ক্লায়েন্ট লিখতে খুব সহজ। এখানে একটি
https://github.com/pedro-vicente/lib_netsockets
এটি ওয়েব সার্ভার থেকে একটি ফাইল পুনরুদ্ধার করতে HTTP GET ব্যবহার করে, সার্ভার এবং ফাইল উভয়ই কমান্ড লাইন প্যারামিটার। রিমোট ফাইলটি স্থানীয় কপির সাথে সংরক্ষিত হয়েছে।
দাবি অস্বীকার: আমি লেখক
সম্পাদনা: সম্পাদিত ইউআরএল
মনে রাখবেন যে এর জন্য লাইবকারল, উইন্ডোজ।, বা উইনসক প্রয়োজন হয় না! লাইব্রেরিগুলির সংকলন, কোনও প্রকল্প কনফিগারেশন ইত্যাদি নেই আমার উইন্ডোজ 10 এ ভিজুয়াল স্টুডিও 2017 সি ++ এ কাজ করছে এই কোডটি:
#pragma comment(lib, "urlmon.lib")
#include <urlmon.h>
#include <sstream>
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();
আমি কীভাবে এটি করব তা বুঝতে পেরেছিলাম, যেহেতু আমি একটি সহজ এপিআই অ্যাক্সেস স্ক্রিপ্ট চেয়েছিলাম, লাইবাকুর্লের মতো লাইব্রেরিগুলি আমাকে সমস্ত ধরণের সমস্যা ঘটাচ্ছে (এমনকি আমি যখন নির্দেশাবলী অনুসরণ করেছি ...), এবং উইনসক খুব নীচের স্তরের এবং জটিল ।
আমি সমস্ত আইএসট্রিম রিডিং কোড সম্পর্কে বিশেষভাবে নিশ্চিত নই (বিশেষত সময়ের শর্তটি - নিখরচায় / উন্নতি করতে নির্দ্বিধায়) তবে ওহে, এটি কাজ করে , ঝামেলা মুক্ত! (এটা আমার যে জ্ঞান করে তোলে, যেহেতু আমি একটি ব্যবহৃত ব্লক (সমলয়) কলের , এই জরিমানা, যে bytesRead
> সবসময় হবে 0U প্রবাহ পর্যন্ত ( ISequentialStream ?) পড়া শেষ তবে কে জানে।)
আরও দেখুন: ইউআরএল মনিকার্স এবং অ্যাসিক্রোনাস প্লাগেবল প্রোটোকল রেফারেন্স
2020 এপ্রিলের জন্য আপডেট হওয়া উত্তর:
সিপিপি-httplib (ক্লায়েন্ট এবং সার্ভার উভয় হিসাবে) সহ আমি সম্প্রতি প্রচুর সাফল্য পেয়েছি । এটি পরিপক্ক এবং এটির আনুমানিক, একক থ্রেডযুক্ত আরপিএস প্রায় 6 কে।
রক্তপাতের প্রান্তে, সত্যিকার অর্থে প্রতিশ্রুতিবদ্ধ একটি কাঠামো, সিপিভি-ফ্রেমওয়ার্ক রয়েছে যা দুটি কোরে প্রায় 180k আরপিএস পেতে পারে (এবং কোর সংখ্যাটি ভালভাবে স্কেল করবে কারণ এটি সমুদ্রের কাঠামোর উপর ভিত্তি করে , যা দ্রুততম ডিবিগুলিকে ক্ষমতা দেয় গ্রহ, সাইক্ল্যাডব )।
তবে সিপিভি-কাঠামো এখনও অপেক্ষাকৃত অপরিণত; সুতরাং, বেশিরভাগ ব্যবহারের জন্য, আমি চূড়ান্তভাবে সিপিপি-httplib প্রস্তাব দিই।
এই প্রস্তাবটি আমার পূর্ববর্তী উত্তর (8 বছর আগে) প্রতিস্থাপন করে ।
এখানে কয়েকটি (অপেক্ষাকৃত) সহজ সি ++ 11 কোড যা একটি ইউআরএল এর সামগ্রী ডাউনলোড করতে libCURL ব্যবহার করে std::vector<char>
:
# pragma once
#include <string>
#include <vector>
std::vector<char> download(std::string url, long* responseCode = nullptr);
#include "http_download.hh"
#include <curl/curl.h>
#include <sstream>
#include <stdexcept>
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);
}
সাধারণত আমি ক্রস-প্ল্যাটফর্মের মতো সিআরএল, পোকো, বা কিউটি জাতীয় কিছু সুপারিশ করতাম। তবে, এখানে একটি উইন্ডোজ উদাহরণ!
#include <atlbase.h>
#include <msxml6.h>
#include <comutil.h> // _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();
আপনি যদি সি ++ তে এইচটিটিপি ক্লায়েন্ট লাইব্রেরি খুঁজছেন যা বিশ্রামের ওয়েব পরিষেবাগুলি গ্রাহ্য করার জন্য একাধিক প্ল্যাটফর্মগুলিতে (লিনাক্স, উইন্ডোজ এবং ম্যাক) সমর্থিত। আপনি নীচের বিকল্প থাকতে পারে।
যদিও কিছুটা দেরি হয়েছে। আপনি https://github.com/Taymindis/backcurl পছন্দ করতে পারেন ।
এটি আপনাকে মোবাইল সি ++ বিকাশে HTTP কল করতে দেয়। মোবাইল গেম বিকাশের জন্য উপযুক্ত for
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
এটি করার জন্য আপনি এসিই ব্যবহার করতে পারেন:
#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;
}