مقدمة: لماذا كتابة عميل HTTP بلغة C++؟
في التطوير الحديث، أصبح التفاعل مع خدمات الويب جزءًا لا يتجزأ من أي تطبيق تقريبًا. حتى إذا كنت تكتب برنامجًا سطح المكتب بلغة C++، فستحتاج عاجلاً أم آجلاً إلى إرسال بيانات إلى الخادم أو استلامها منه. على عكس لغات البرمجة النصية، لا تحتوي لغة C++ على أدوات مدمجة للعمل مع HTTP - ولكن هذه ليست مشكلة. هناك عدة طرق مجربة لتنفيذ عميل HTTP بلغة C++، وسنقوم بشرحها من البسيط إلى المعقد.
في هذه المقالة، سنتناول:
- كيفية استخدام مكتبة libcurl - المعيار الذهبي للعمل مع HTTP في C++
- كيفية إرسال طلبات GET و POST مع الرؤوس والمحتوى
- كيفية معالجة الرد المستلم وتحليل JSON
- كيفية تجنب الأخطاء الشائعة عند العمل مع طلبات الشبكة
جميع أمثلة الكود يمكن استخدامها فورًا في مشاريعك. هيا بنا!
1. اختيار المكتبة: libcurl كأداة رئيسية
كتابة عميل HTTP بلغة C++ من الصفر هي مهمة غير مجدية. ستحتاج إلى العمل مع sockets، وتشكيل الرؤوس يدويًا، وتحليل الردود، ومعالجة الكثير من الحالات الحدية. لحسن الحظ، توجد libcurl - مكتبة قوية ومستقرة ومتعددة المنصات تقوم بكل العمل الشاق نيابة عنك.
للبدء، قم بتثبيت libcurl. على Ubuntu يتم ذلك بأمر واحد:
sudo apt-get install libcurl4-openssl-devعلى Windows يمكنك استخدام vcpkg أو تنزيل الملفات الثنائية الجاهزة. بعد التثبيت، قم بتوصيل المكتبة في ملف CMakeLists.txt الخاص بك أو ببساطة قم بالربط يدويًا باستخدام الأعلام -lcurl.
الهيكل الأساسي للعمل مع libcurl هو نفسه دائمًا:
- نقوم بتهيئة السياق العام باستدعاء
curl_global_init() - نقوم بإنشاء واصف جلسة
curl_easy_init() - نقوم بتعيين معلمات الطلب (URL، الرؤوس، الطريقة، إلخ)
- نقوم بتنفيذ الطلب
curl_easy_perform() - نقوم بتنظيف الموارد
يبدو الأمر بسيطًا؟ دعنا ننتقل إلى الكود.
2. إرسال طلبات GET و POST: أمثلة عملية
2.1 طلب GET بسيط
لنبدأ بالكلاسيكيات - نحصل على بيانات من API عام. لنفترض أننا نريد معرفة سعر Bitcoin الحالي مقابل الدولار:
#include <iostream>#include <string>#include <curl/curl.h>
// دالة رد الاتصال لكتابة البيانات إلى سلسلة نصيةstatic size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) { ((std::string*)userp)->append((char*)contents, size * nmemb); return size * nmemb;}
int main() { curl_global_init(CURL_GLOBAL_DEFAULT); CURL* curl = curl_easy_init(); std::string response; if (curl) { curl_easy_setopt(curl, CURLOPT_URL, "https://api.coindesk.com/v1/bpi/currentprice.json"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { std::cerr << "خطأ: " << curl_easy_strerror(res) << std::endl; } else { std::cout << "رد الخادم:" << response << std::endl; } curl_easy_cleanup(curl); } curl_global_cleanup(); return 0;}لاحظ دالة رد الاتصال WriteCallback. لا تعرف libcurl أين تحفظ البيانات، لذلك نمرر مؤشرًا إلى سلسلة نصية ونكتب فيها مع تدفق البيانات. هذا هو النمط القياسي.
2.2 طلب POST مع محتوى JSON
الآن سنرسل بيانات إلى الخادم. لنفترض أننا نسجل مستخدمًا:
#include <iostream>#include <string>#include <curl/curl.h>
int main() { curl_global_init(CURL_GLOBAL_DEFAULT); CURL* curl = curl