بالنسبة للتطبيقات في الوقت الفعلي أو الألعاب في الوقت الفعلي ، غالبًا ما لا يستطيع بروتوكول HTTP تلبية احتياجاتنا. المقبس عملي للغاية بالنسبة لنا. فيما يلي ملاحظات لهذه الدراسة. يشرح بشكل أساسي جوانب نوع الاستثناء ، ومبدأ التفاعل ، والمقبس ، و Serversocket ، و Multithreading.
نوع الاستثناء
قبل فهم محتوى المقبس ، تحتاج إلى فهم بعض أنواع الاستثناءات المعنية. يتم موروثة الأنواع الأربعة التالية من IOException ، حيث تظهر الكثير من IOException مباشرة بعد ذلك.
unkownhostexception: اسم المضيف أو خطأ IP
ConnectException: يرفض الخادم الاتصال ، لا يبدأ الخادم ، (يتجاوز عدد قوائم الانتظار ، يتم رفض الاتصال)
SockettimeOutException: مهلة الاتصال
BindException: لا يمكن ربط كائن المقبس بعنوان أو منفذ IP المحلي المصمم
عملية التفاعل
أعتقد أن الصورة التالية قد تم شرحها بالتفصيل ووضوح.
المقبس
مُنشئ
Socket () Socket (عنوان inetaddress ، منفذ int) يلقي unknownhostexception ، ioExceptionSocket (عنوان inetaddress ، int port ، inetaddress localaddress ، int localport) يلقي ioExceptionSocket (string host ، int port) inthostexception ، ioexceptionsocket ، intadddress localeaddress ، introwser introwser introwsexpress ، introwser introwser) introwsexpress ، introwsex introwsex.
باستثناء الأول بدون معلمات ، سيحاول المُنشئون الآخرون إنشاء اتصال بالخادم. إذا فشلت ، سيتم إلقاء خطأ ioException. إذا نجحت ، يتم إرجاع كائن المقبس.
Inetaddress هو فئة تستخدم لتسجيل المضيف. يمكن لـ GethostbyName الثابتة (سلسلة MSG) إرجاع مثيل ، ويمكن أيضًا الحصول على طريقة ثابتة GetLocalhost () أيضًا الحصول على عنوان IP للمضيف الحالي وإرجاع مثيل. تعد معلمات المقبس (مضيف السلسلة ، ومنفذ int ، و inetaddress localaddress ، و int localport) مُنشئ IP الهدف ، ومنفذ الهدف ، و IP المحلي ، والمنفذ المحلي.
طريقة المقبس
getInetaddress () ؛ عنوان IP للخادم البعيد
getPort () ؛ منفذ الخادم البعيد
عنوان IP getlocaladdress () للعميل المحلي
منفذ GetLocalport () من العميل المحلي
getInputStream () ؛ getInputStream () ؛
getOutStream () ؛ الحصول على دفق الإخراج
تجدر الإشارة إلى أنه من بين هذه الطرق ، فإن أهمها هي getInputStream () و GetOutputStream ().
حالة المقبس
isclosed () ؛ // هل الاتصال مغلق؟ إذا أغلقت ، ارجع صحيحًا ؛ خلاف ذلك ، العودة كاذبة
iSconnect () ؛ // إرجاع صحيح إذا كان متصلاً ؛ خلاف ذلك العودة كاذبة
isBound () ؛ // إذا كان المقبس مرتبطًا بمنفذ محلي ، فاحرص على العودة ؛ خلاف ذلك ، العودة كاذبة
إذا كنت ترغب في تأكيد ما إذا كانت حالة المقبس في اتصال ، فإن البيان التالي هو وسيلة جيدة للحكم.
iSconnection boolean = socket.isconnected () &&! socket.isclosed () ؛ // احكم إذا كان ذلك يتعلق حاليًا بالاتصال
مقبس شبه مغلق
في كثير من الأحيان ، لا نعرف المدة التي يستغرقها الانتهاء في دفق الإدخال الذي تم الحصول عليه. فيما يلي بعض الطرق الشائعة:
Serversocket
مُنشئ
ServersOcket () يلقي iOexceptionServersOctocket (منفذ int) يلقي ioExceptionServersOction (منفذ int ، int backlog) يلقي ioExceptionServersOcket
ملحوظة:
1. المنفذ الذي سيتم الاستماع إليه بواسطة خادم المنفذ ؛ طول قائمة الانتظار لطلب اتصال عميل Backlog ؛ يربط خادم bindaddr IP
2. إذا كان المنفذ مشغولًا أو لم يكن لديه إذن لاستخدام منافذ معينة ، فسيتم إلقاء خطأ BindException. على سبيل المثال ، تتطلب المنافذ من 1 إلى 1023 من المسؤول الحصول على إذن.
3. إذا تم تعيين المنفذ على 0 ، فسيقوم النظام تلقائيًا بتعيين منفذ له ؛
4. يتم استخدام bindaddr لربط خادم IP. لماذا يوجد مثل هذا الإعداد؟ على سبيل المثال ، تحتوي بعض الآلات على بطاقات شبكة متعددة.
5. بمجرد ربط Serversocket بمنفذ الاستماع ، لا يمكن تغييره. يمكن لـ ServersOcket () تعيين معلمات أخرى قبل ربط المنفذ.
مثال خادم واحد
service public void service () {بينما (صحيح) {Socket Socket = null ؛ حاول {socket = serversocket.accept () ؛ // اتخاذ اتصال من قائمة انتظار الاتصال ، إذا لم يكن الأمر كذلك ، انتظر system.out.println ("العنوان:"+socket.getinetaddress ()+":"+socket.getport ()) ؛ ... // استقبال وإرسال البيانات} catch (ioException e) {ServersiteCound Multithed
وغني عن القول أن فوائد متعدد الخيوط هي متعددة الخيوط ، ومعظم السيناريوهات متعددة الخيوط. سواء كانت ألعابنا في الوقت الفعلي أو IM ، فإن الاحتياجات متعددة الخيوط ضرورية. دعنا نتحدث عن طريقة التنفيذ أدناه:
الطرق التي تنفذ متعدد الخيوط إما ترث فئة مؤشرات الترابط أو تنفيذ واجهة Runnable. بالطبع ، يمكن أيضًا استخدام تجمعات الخيوط ، ولكن جوهر التنفيذ متشابه.
هنا مثال:
الرمز التالي هو الموضوع الرئيسي للخادم. تعيين موضوع عامل لكل عميل:
service public void service () {بينما (صحيح) {Socket Socket = null ؛ حاول {socket = serversocket.accept () ؛ // يحصل مؤشر الترابط الرئيسي على مؤشر ترابط العميل workthread = مؤشر ترابط جديد (معالج جديد (مقبس)) ؛ // إنشاء مؤشر ترابط workthread.start () ؛ // start thread} catch (استثناء e) {E.PrintStackTrace () ؛ }}}بالطبع ، ينصب التركيز هنا على كيفية تنفيذ فئة المعالج. يحتاج المعالج إلى تنفيذ واجهة Runnable:
معالج الفئة ينفذ Runnable {Socket Socket ؛ المعالج العام (مقبس المقبس) {this.socket = socket ؛ } public void run () {try {system.out.println ("اتصال جديد:"+socket.getInetAddress ()+":"+socket.getport ()) ؛ thread.sleep (10000) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛} أخيرًا {try {system.out.println ("أغلق الاتصال:"+socket.getInetAddress ()+":"+socket.getport ()) ؛ if (socket! = null) socket.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }}}} بالطبع ، هناك طرق أخرى للترابط أولاً ، مثل برك الخيوط ، أو برك الخيوط المدمجة في JVM. لن أشرح ذلك هنا.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.