من المعروف جيدًا أن الاتصال بين خادم الويب والعميل يستخدم بروتوكول HTTP. HTTP هو معيار لطلبات واستجابات الخادم العميل والخادم (TCP). نظرًا لأن بروتوكول HTTP يعتمد على بروتوكول TCP ، سأستخدم المقبس في Java لإكمال خادم الويب البسيط هذا. لمزيد من معلومات HTTP مفصلة ، يمكنك استشارة المعلومات ذات الصلة للتعرف عليها.
قبل كتابة الخادم ، دعونا نلقي نظرة على قواعد الاتصال بين المتصفح والخادم.
بادئ ذي بدء ، نستخدم ServersOcket لمحاكاة الخادم ، والوصول إليه من خلال المتصفح ، وعرض المحتوى المطلوب من قبل المتصفح:
استيراد java.io.bufferedWriter ؛ استيراد java.io.inputstream ؛ استيراد java.io.outputstreamwriter Author jianggujin * */فئة عامة hqhttprotocoltest {test public void server () رمي الاستثناء {serversocket serversocept = new Serversocket (80) ؛ Socket Socket = ServersOcket.accept () ؛ دفق inputStream = socket.getInputStream () ؛ int r = -1 ؛ بينما ((r = dream.read ())! = -1) {system.out.print ((char) r) ؛ }}}قم بتشغيله مع Junit والوصول إليه من خلال المتصفح: http://127.0.0.1 ، يمكننا أن نرى أن إخراج محتوى طلب المتصفح على وحدة التحكم هو كما يلي:
Get/http/1.1host: 127.0.0.1connection: keep-aliveAcpt: text/html ، application/xhtml+xml ، application/xml ؛ q = 0.9 ، image/webp ،*/*؛ chrome/31.0.1650.63 Safari/537.36Accept-encoding: gzip ، deflate ، sdchaccept-language: Zh-Cn ، Zh ؛ q = 0.8
من أجل تحليل محتوى الطلب بشكل أفضل ، نكتب صفحة HTML لإرسال بعض البيانات وعرض محتوى الطلب مرة أخرى:
<! doctype html> <html> <head> <meta charset = "utf-8"> <title> اختبار </title> </head> <body> <method method = "post" Action = "http://127.0.0.1؟test=123 اكتب = "إرسال"/> </form> </body> </html>
أدخل BOB في مربع الإدخال ، انقر فوق الزر لإرساله ، ومراقبة إخراج وحدة التحكم:
post/؟ test = 123 http/1.1host: 127.0. (Windows NT 5.1) AppleWebkit/537.36 (KHTML ، مثل Gecko) Chrome/31.0.1650.63 Safari/537.36-Content-Type: Application/x-www-form-urlencodedaccept-encding: gzip ، deflate ،
دعونا نحلل محتوى هذا الطلب:
السطر الأول: يتكون من ثلاثة أجزاء ، مفصولة بمسافات في الوسط ، الجزء الأول هو طريقة الطلب (GET ، POST) ، والجزء الثاني هو مسار الطلب والاستعلام ، والجزء الثالث هو إصدار بروتوكول HTTP (HTTP/1.1)
السطر 2 إلى السطر 10: يتم تمرير معلومات الرأس للطلب ، واسم وقيمة رأس الطلب: افصل الخط الحادي عشر: السطر الفارغ السطر الثاني عشر: محتوى النموذج المقدم ، يمكننا الحصول على الاستنتاج التالي: السلوك الأول لمعلومات الطلب هو طريقة الطلب ، ومسار الطلب ، ومعلمات Query ، ونسخة بروتوكول HTTP. بعد استراحة السطر /r /n ، تتبع معلومات رأس الطلب فورًا فاصل الخط /r /n ، ويتبع معلومات رأس الطلب خط فارغ بعد اكتمال معلومات رأس الطلب ، ويتبع بيانات الطلب مباشرة خط فارغ. تجدر الإشارة إلى أن هذا محاكاة فقط. بالنسبة لتقديمات الملفات المعقدة ، وما إلى ذلك ، لا تتم مناقشتها هنا ، وتنسيق محتوى الطلب مختلف قليلاً.
في هذه المرحلة ، عرفنا بالفعل المحتوى الذي طلبه العميل. دعنا نلقي نظرة على تنسيق بيانات استجابة الخادم بعد تلقي الطلب. نقوم بإنشاء مشروع ويب جديد لاختبار وتحرير محتوى صفحة HTML على النحو التالي:
<! doctype html> <html> <head> <meta charset = "utf-8"> <title> اختبار </title> </head> <body> هذه هي صفحة اختبار. </body> </html>
ابدأ الخادم ، ثم اكتب رمز اختبار العميل للحصول على بيانات إرجاع الخادم:
استيراد java.io.bufferedWriter ؛ استيراد java.io.inputstream ؛ استيراد java.io.outputstreamwriter خادم باطل عام () يلقي الاستثناء {serversocket serversite = new ServersOcket (80) ؛ Socket Socket = ServersOcket.accept () ؛ دفق inputStream = socket.getInputStream () ؛ // bufferedInputStream inputStream = جديد bufferedInputStream (تيار) ؛ int r = -1 ؛ بينما ((r = dream.read ())! = -1) {system.out.print ((char) r) ؛ } }test public void client () يلقي استثناء {Socket Socket = New Socket ("127.0.0.1" ، 80) ؛ bufferedWriter Writer = new BufferedWriter (New OutputStreamWriter (Socket.getOutputStream ())) ؛ Writer.write ("get /servlet/test.html http/1.1/r/n") ؛ Writer.Write ("المضيف: 127.0.0.1/r/n") ؛ Writer.write ("الاتصال: keep-alive/r/n") ؛ Writer.Write ("قبول: Text/HTML ، Application/XHTML+XML ، Application/XML ؛ Q = 0.9 ، Image/WebP ،*/*؛ Q = 0.8/R/N") ؛ Writer.Write ("User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebkit/537.36 (KHTML ، مثل Gecko) Chrome/31.0.1650.63 Safari/537.36/R/N") ؛ Writer.Write ("قبول الترميز: gzip ، deflate ، sdch/r/n") ؛ Writer.Write ("قبول باللغة: ZH-CN ، ZH ؛ Q = 0.8/r/n") ؛ Writer.write ("/r/n") ؛ الكاتب. flush () ؛ دفق inputStream = socket.getInputStream () ؛ int r = -1 ؛ بينما ((r = dream.read ())! = -1) {system.out.print ((char) r) ؛ }}}يقوم تشغيل البرنامج للحصول على الخادم بإرجاع المحتوى التالي:
http/1.1 200 okserver: apache-coyote/1.1Accept-Ranges: bytesetag: w/"129-1456125361109" Last-modied: Mon ، 22 Feber 2016 07:16:01 GMTContent-Type: HTMLCONT-Lengle: 129Date: gmt <! doctype html> <html> <head> <head> <meta charset = "utf-8" <title> اختبار </title> </head> <body> هذه هي صفحة الاختبار. </body> </html>
وبالمثل ، دعنا نحلل رسالة الإرجاع هذه:
يتكون السطر الأول من ثلاثة أجزاء ، مفصولة بمسافات في الوسط ، الجزء الأول هو إصدار بروتوكول HTTP (HTTP/1.1) ، والجزء الثاني هو رمز حالة الاستجابة ، والجزء الثالث هو وصف حالة الاستجابة للخط الثاني للخط المليء بالاستجابة: الخلاصة: أول شيء هو إصدار بروتوكول HTTP معلومات الطلب ، ورمز حالة الاستجابة ، ووصف حالة الاستجابة ، ومعلومات رأس الاستجابة يتبعها عملية استراحة السطر /R /N ، ويتم تمرير معلومات رأس الاستجابة عن طريق كسر السطر /N ، وينتبع معلومات رأس الاستجابة بواسطة خط فارغ بعد اكتمال معلومات رأس الاستجابة ، وتتبع بيانات الاستجابة فورًا. تجدر الإشارة إلى أنه بالإضافة إلى هذا الاستجابة ، هناك بالفعل طرق أخرى مقابلة ، مثل القطع ، والتي لم تتم مناقشتها هنا ، ويمكنك التحقق من المعلومات ذات الصلة.
حتى الآن ، قمنا بتحليل تنسيق محتوى طلب العميل وتنسيق المحتوى المقابل للخادم. هذه المقالة تنتهي هنا. آمل أن يكون ذلك مفيدًا لتعلم الجميع.