يعد Socket ، المعروف أيضًا باسم Sockets ، أحد التقنيات الأساسية لاتصالات شبكة الكمبيوتر. اليوم ، يتم تنفيذ معظم البرامج المستندة إلى الويب ، مثل المتصفحات وأدوات المراسلة الفورية وحتى تنزيلات P2P ، بناءً على المقبس. ستقدم هذه المقالة برمجة المقبس استنادًا إلى TCP/IP وكيفية كتابة برنامج عميل/خادم.
الحلوى قبل العشاء
يتبع نظام الإدخال والإخراج (IO) UNIX قوالب التشغيل مثل القراءة المفتوحة والكتابة. قبل إجراء عملية المستخدم عمليات IO ، تحتاج إلى الاتصال مفتوحًا لتحديد الأذونات والحصول عليها للملف أو الجهاز للقراءة أو الكتابة. بمجرد فتح كائن تشغيل IO ، يمكن لعملية المستخدم إجراء عمليات أو أكثر من القراءة أو الكتابة على الكائن. يتم استخدام عملية القراءة لقراءة البيانات من كائنات تشغيل IO وتمرير البيانات إلى عملية المستخدم. يتم استخدام عملية الكتابة لتمرير (كتابة) بيانات في عمليات المستخدم إلى كائنات تشغيل IO. بعد اكتمال كل عمليات القراءة والكتابة ، تحتاج عملية المستخدم إلى الاتصال بالقرب من إخطار النظام بأنه يكمل استخدامه لكائن IO.
عندما بدأت UNIX في دعم Interprocess Communication (IPC) ، تم تصميم واجهة IPC لتكون مماثلة لواجهة تشغيل ملف IO. في UNIX ، ستحتوي العملية على مجموعة من واصفات IO التي يمكن قراءتها وكتابتها. يمكن أن يكون واصف IO ملفًا أو جهازًا أو قناة اتصال (مقبس المقبس). يتكون واصف الملف من ثلاثة أجزاء: إنشاء (فتح المقبس) ، وقراءة وكتابة البيانات (قبول وإرسال إلى المقبس) وتدمير (مقبس إغلاق).
في أنظمة UNIX ، يتم تطبيق الإصدار الشبيه بـ BSD من واجهة IPC كطبقة أعلى من بروتوكولات TCP و UDP. يتم تمثيل وجهة الرسالة بعنوان المقبس. عنوان المقبس هو معرف اتصال يتكون من عنوان شبكة ورقم منفذ.
تتطلب عمليات الاتصال بين العمليات زوجًا من المقابس. يتم إجراء اتصال بين العمليات عن طريق نقل البيانات بين مقبس في عملية واحدة ومقبس آخر في عملية أخرى. عند تنفيذ رسالة وإرسالها ، يتم تصنيع الرسالة في المقبس في نهاية إرسال حتى يرسل بروتوكول الشبكة ذات المستوى الأدنى الرسائل. عندما تصل الرسالة إلى المقبس في الطرف المتلقي ، ستكون أيضًا في قائمة انتظار حتى تتلقى العملية في الطرف المتلقي الرسالة.
الاتصالات TCP و UDP
فيما يتعلق برمجة المقبس ، لدينا بروتوكولات اتصال للاختيار من بينها. واحد هو اتصال البيانات ، والآخر هو دفق الاتصال.
اتصال البيانات
بروتوكول اتصال بيانات البيانات هو ما نسميه غالبًا UDP (بروتوكول بيانات المستخدم). UDP هو بروتوكول بدون اتصال ، مما يعني أنه في كل مرة نرسل بيانات البيانات ، نحتاج إلى إرسال واصف المقبس للجهاز الأصلي وواصف المقبس للمستقبل في نفس الوقت. لذلك ، نحتاج إلى إرسال بيانات إضافية في كل مرة نتواصل فيها.
تيار الاتصال
يسمى بروتوكول اتصال الدفق ، والمعروف أيضًا باسم TCP (بروتوكول التحكم في النقل) أيضًا TCP (بروتوكول التحكم في النقل). على عكس UDP ، TCP هو بروتوكول قائم على الاتصال. قبل استخدام اتصال الدفق ، يجب علينا إنشاء اتصال بين زوج التواصل من المقابس. يعد أحد المقابس بمثابة الخادم للاستماع إلى طلبات الاتصال. الطرف الآخر يقدم طلبات الاتصال كعميل. بمجرد قيام المآخذين بإنشاء اتصال ، يمكنهما نقل البيانات في اتجاه واحد أو في اتجاهين.
بعد قراءة هذا ، لدينا بعض الأسئلة حول ما إذا كنا نستخدم UDP أو TCP لبرمجة المقبس. يعتمد اختيار برمجة المقبس بناءً على البروتوكول الذي يعتمد على سيناريو التطبيق المحدد على برنامج خادم العميل المحدد. أدناه ، نحلل باختصار الفرق بين بروتوكولات TCP و UDP ، مما قد يساعدك على اختيار أي واحد لاستخدامه بشكل أفضل.
في UDP ، في كل مرة يتم فيها إرسال مخطط بيانات ، يجب تضمين واصف المقبس للجهاز الأصلي وواصف المقبس للمستقبل. نظرًا لأن TCP عبارة عن بروتوكول قائم على الاتصال ، يجب إنشاء اتصال بين أزواج مقبس الاتصال قبل الاتصال ، لذلك سيكون هناك برمجة اتصال تستغرق وقتًا في بروتوكول TCP.
في UDP ، تحتوي بيانات DataGram على حد 64 كيلو بايت في الحجم. لا يوجد مثل هذا القيود في TCP. بمجرد قيام زوج التوصيل من TCP بإنشاء اتصال ، يكون الاتصال بينهما مشابهًا لتيار IO ، وسيتم قراءة جميع البيانات بالترتيب الذي يتم قبوله.
UDP هو بروتوكول غير موثوق به ، ولا يتم قبول مخططات البيانات المرسلة بالضرورة من قبل المقبس المستلم بالترتيب الذي يتم إرساله به. ثم TCP هو بروتوكول موثوق. يتسق ترتيب الحزم التي تلقاها الطرف المتلقي مع ترتيب الحزم في نهاية إرسال.
باختصار ، يعد TCP مناسبًا لخدمات الشبكة مثل تسجيل الدخول عن بُعد (Rlogin ، Telnet) ونقل الملفات (FTP). لأن حجم هذه البيانات التي تحتاج إلى نقل غير مؤكد. UDP أبسط وأخف وزنا من TCP. يتم استخدام UDP لتنفيذ بعض الخدمات التي تكون في الوقت الفعلي أكثر أو ليس لها أهمية لفقدان الحزم. معدل فقدان الحزمة UDP في LAN منخفض نسبيا.
برمجة المقبس في جافا
في القسم التالي ، سأشرح كيفية استخدام المقبس لكتابة برامج العميل والخادم من خلال بعض الأمثلة.
ملاحظة: في المثال التالي ، سأستخدم برمجة المقبس استنادًا إلى بروتوكول TCP/IP ، لأن هذا البروتوكول يستخدم على نطاق أوسع بكثير من UDP/IP. توجد جميع الفئات المتعلقة بالمقبس تحت حزمة Java.net ، لذلك نحتاج إلى تقديم هذه الحزمة عندما نقوم ببرمجة المقبس.
كتابة العميل
قم بتشغيل المقبس
إذا كنت على جانب العميل ، فأنت بحاجة إلى كتابة الرمز التالي لفتح مأخذ توصيل.
string host = "127.0.0.1" ؛ int port = 8919 ؛ Socket Client = New Socket (Host ، Port) ؛
في الرمز أعلاه ، يكون المضيف هو الجهاز الذي يحتاج العميل إلى الاتصال به ، والمنفذ هو المنفذ الذي يستخدمه الخادم للاستماع إلى الطلب. عند اختيار منفذ ، هناك شيء واحد تحتاج إلى الانتباه إليه هو أن المنافذ مثل 0 ~ 1023 قد تم حجزها بواسطة النظام. يتم استخدام هذه المنافذ من قبل بعض الخدمات الشائعة الاستخدام ، مثل Mail و FTP و HTTP. عند كتابة رمز من جانب الخادم وتحديد منفذ ، يرجى تحديد منفذ أكبر من 1023.
اكتب البيانات
التالي هو كتابة بيانات الطلب. نحصل على كائن OutputStream من كائن مقبس العميل ثم كتابة البيانات. يشبه إلى حد كبير رمز معالجة ملف IO.
فئة عامة clientsocket {public static void main (String args []) {String Host = "127.0.0.1" ؛ INT PORT = 8919 ؛ Try {Socket Client = New Socket (Host ، Port) ؛ كاتب الكاتب = جديد outputStreamWriter (client.getOutputStream ()) ؛ Writer.write ("مرحبًا من العميل") ؛ الكاتب. flush () ؛ الكاتب. client.close () ؛ } catch (ioException e) {E.PrintStackTrace () ؛ }}}أغلق كائن IO
على غرار ملف IO ، بعد قراءة البيانات وكتابةها ، نحتاج إلى إغلاق كائن IO لضمان الإصدار الصحيح للموارد.
الكتابة من جانب الخادم
افتح المقبس من جانب الخادم
منفذ int = 8919 ؛ خادم ServersOcket = ServersOcket (PORT) ؛ Socket Socket = server.accept () ؛
يقوم الرمز أعلاه بإنشاء مقبس من جانب الخادم ، ثم يستدعي طريقة القبول للاستماع والحصول على مقبس طلب العميل. طريقة القبول هي طريقة حظر تنتظر الحظر حتى يتم الاتصال بين الخادم والعميل.
قراءة البيانات
احصل على كائن inputStream من خلال كائن المقبس الذي تم الحصول عليه أعلاه ، ثم قم بتثبيت ملف IO لقراءة البيانات. هنا نطبع المحتوى.
الفئة العامة serverClient {public static void main (string [] args) {int port = 8919 ؛ جرب {serversocket server = new servers (port) ؛ Socket Socket = server.accept () ؛ reader reader = new inputStreamReader (socket.getInputStream ()) ؛ char chars [] = new Char [1024] ؛ int len ؛ StringBuilder Builder = new StringBuilder () ؛ بينما ((len = reader.read (chars))! = -1) {builder.append (سلسلة جديدة (chars ، 0 ، len)) ؛ } system.out.println ("استلام من رسالة العميل =:" + builder) ؛ reader.close () ؛ socket.close () ؛ server.close () ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ }}}أغلق كائن IO
لا يمكن نسيانها. أخيرًا ، أحتاج إلى إغلاق كائن IO بشكل صحيح لضمان الإصدار الصحيح للموارد.
لاحظ مثالاً
هنا نضيف مثالاً ، باستخدام Socket لتنفيذ خادم Echo ، أي أن الخادم سيمرر البيانات المرسلة من العميل إلى العميل. الكود بسيط للغاية.
استيراد java.io.*؛ استيراد java.net.*؛ echoserver public {public static void main (سلسلة args []) {// قسم الإعلان: // إعلان مقبس خادم ومقبس عميل للخادم // إعلان إدخال ودفق خوادم ServerSocket echoserver = null ؛ خط السلسلة DatainputStream هو ؛ printstream OS ؛ socket clientsocket = null ؛ // حاول فتح مقبس خادم على المنفذ 9999 // لاحظ أنه لا يمكننا اختيار منفذ أقل من 1023 إذا لم نكن مستخدمين متميزين (جذر) حاول {echoServer = New Serversocket (9999) ؛ } catch (ioException e) {system.out.println (e) ؛ } // قم بإنشاء كائن مقبس من Serversocket للاستماع وقبول الاتصالات. // فتح تدفقات الإدخال والإخراج {clientsocket = echoServer.accept () ؛ IS = جديد datainputStream (clientsocket.getInputStream ()) ؛ OS = new printStream (clientsocket.getOutputStream ()) ؛ // طالما نتلقى البيانات ، صدى أن البيانات مرة أخرى إلى العميل. بينما (صحيح) {line = is.ReadLine () ؛ OS.Println (الخط) ؛ }} catch (ioException e) {system.out.println (e) ؛ }}}قم بتجميع وتشغيل الرمز أعلاه وقدم الطلب التالي ، يمكنك رؤية محتوى البيانات التي يحملها طلب العميل.
15:00 $ CURL http://127.0.0.1:9999/؟111GET/؟ 111 HTTP/1.1USER-AGENT: CURL/7.37.1HOST: 127.0.0.1:9999ACTEP: */ *
لخص
من المثير للاهتمام للغاية أداء برمجة خادم العميل ، وبرمجة المقبس في Java أسهل وأسرع من اللغات الأخرى (مثل C).
تحتوي حزمة Java.net على العديد من الفصول القوية والمرنة للمطورين لشبكات البرمجة. عند شبكات البرمجة ، يوصى باستخدام واجهة برمجة التطبيقات أدناه هذه الحزمة. في الوقت نفسه ، تحتوي حزمة SUN. بالإضافة إلى ذلك ، لا يمكن ضمان تضمين هذه الحزمة على جميع المنصات.
ما سبق هو مجموعة من معلومات مقبس Java. سوف نستمر في إضافة المعرفة ذات الصلة في المستقبل. شكرا لدعمكم لهذا الموقع!