Home برمجة سي/سي++ ارسال واستقبال البيانات عبر HTTP في Qt
ارسال واستقبال البيانات عبر HTTP في Qt

ارسال واستقبال البيانات عبر HTTP في Qt

64
0

هذه الفترة احتجت ان ارسل HTTP Post Request باستخدام Qt واقوم بارسال ملفات للسيرفر (عباره عن شهاده
رقمية Certificate للكلاينت بالاضافه الى بعض الملفات الأخرى) ، وايضاً احتجت ان اقوم بعمل Get Request من السيرفر وارسل ID
ومن خلاله سوف احصل على هذه الملفات التي قمت برفعها في JSON،، وأحببت وضع هذه التدوينه لعلها
تفيد من يريد القيام بنفس المهمه,

في كيوت الكلاس QNetworkAccessManager هو المسؤول عن ارسال والاستقبال الطلبات في الشبكه،
وفي الغالب سوف تحتاج لQNetworkAccessManager واحد في التطبيق، ويحتوى الكلاس على signals تفيد
بان العملية جاري او انها انتهت وايضاً بها دوال لأخذ الطلب الذي تريد وبعض

البيانات الأخرى وترجع QNetworkReply والذي يحتوي على النتيجة الذي ارجعها السيرفر عندما يعالج الطلب.

المثال البسيط الذي تجده في التوثيق Documentation:

هذا المثال يوضح ان ارسلت Get Request وعندما ترجع النتيجة سوف يتم استدعاء replyFinished وحينها يمكنك طباعه النتيجة او حتى مشاهده ال header الخاص بهذا ال response.  من المهم القيام بحذف هذا الناتج QNetworkReply لذلك يمكنك استخدام الدالة delelteLater في الslot :

من المهم معرفه ان دوال الكلاس هي Asynchronous وهي تعني ان الطلب سوف يتم عمله في Thread أخر وعندما ترجع النتيجة سوف يتم استدعاء ال slot الذي قمت بربطه مع ال signal ، لذلك تنفيذ الكود سوف يستمر بعد استدعاء الدالة get، ايضاً الطلبات التي تقوم بعملها سوف توضع في Queue حتى يتم معالجتها ولل HTTP فسوف يتم معالجة 6 طلبات في اللحظة الواحدة من هذا ال queue.

لكن في بعض الأحيان نظراً لتصميم الكلاس أو لسبب أخر هو أنك تريد الحصول على النتيجة فوراً Synchronous بمعنى عندما تستدعي الدالة فلا تريد ان ترجع الا مع النتيجة لذلك في هذه الحالة يمكنك تحريك الEvent loop حتى تتم معالجة هذا الطلب:

في الاكواد السابقة كنا نقوم بعمل ربط QNetworkAccessManager مع الfinished Signal والأمر يعمل بشكل طبيعي، ولكن بعض الأحيان قد تحتاج أن تتصل على السيرفر وتحصل على النتيجة وبناء على تلك النتيجة تقوم بعمل طلب أخر، باستخدام ال Signal السابقة فسوف يتم استدعاء الدالة replyFinished مرة أخرى عندما تقوم بعمل الطلب والسبب هو انك كل الطلبات التي سوف تتم سوف يتم استدعاء هذا الslot:

لذلك من الأفضل ربطها بال QNetworkReply حيث بها نفس ال Signal وبالتالي لكل طلب يمكن ان تكون هناك slot خاصه فيه ، المثال:

المثال اعلاه من المقال الرائع والذي يوضح لماذا يفضل ان تستخدم QNetworkReply في ال Signals:
http://www.johanpaul.com/blog/2011/07/why-qnetworkaccessmanager-should-not-have-the-finishedqnetworkreply-signal/

نتحدث الان عن ال HTTP POST وهناك طريقتين في Qt الأولى تعمل على نسخه 4.8 وما فوق باستخدام الكلاس QHttpMultiPart والثانية تعمل على النسخ القديمة والحديثة وذلك لأننا سنقوم ببناء ال POST Request يدوياً ونقوم بارساله ، لنفرض ان السيرفر به 3 مدخلات ويجب ان تدخل من الكلاينت:

server

المثال باستخدام QHttpMultiPart :

اذا كنت تعمل على نسخ Qt 4.7 وما قبل فلن تستطيع استخدام هذا الكلاس وعليك القيام بالعملية كاملة ، المثال التالي يوضح كيفية بناء ال Request:

اذا كنت تود بارسال HTTP POST بدون ان تحتوى على ملفات فيمكنك استخدام:

طبعاً في حال ارسال بيانات نصية فال MIME Type يكون application/x-www-form-urlencoded وللبيانات الbinary يفضل ان استخدام multipart/form-data والسبب أن الأول قد يرمز البايت البايرني الواحد ب3 بايتات وهذا ما يجعله خيار غير جيد في ارسال البيانات binary. يمكنك معرفة المزيد من هنا مثلاً: http://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data

في الاخير يمكنك عمل Wrapper يسهل لك كل هذا ويجعل الامر اكثر تلقائية بدل من تحديد اسماء الحقول في دالة الارسال ، يمكن عمل الأتي:

ال Implementation :

ويمكن عمل  Singleton Wrapper لل QNetworkAccessManager بحيث تستخدمه في أكثر من مكان:

وأخيراً ال Implementation , وكما تلاحظ فضلت ال Synchronous Way وخصوصاً ان الامر يتم بسرعه :

استخدام الكلاس سوف يكون بهذه الطريقة:

بالنسبة ل Get فهو مجرد استدعاء الدالة Get الموجودة في ال Wrapper ، وبعد الحصول على  JSON Result قد تريد عمل Parse لها ، واذا كانت البيانات بهذه الفورمات :

output

فيمكنك استخدام:

أرجوا أن يفيد هذا ال Wrapper ، ويمكن طرح الأسئلة والملاحظات ان وجدت،،

شكراً لوصولك لهذه النقطة ..

(64)

tags:
وجدي عصام مهندس برمجيات مهتم بعلوم الحاسب وبالأخص مجال الخوارزميات وهندسة البرمجيات وحماية التطبيقات،

LEAVE YOUR COMMENT

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

مشاركة