توفر Java فئتين لبروتوكول TCP، والتي يتم استخدامها في البرمجة من جانب العميل والبرمجة من جانب الخادم على التوالي. قبل أن يبدأ التطبيق الاتصال، يجب إنشاء اتصال أولاً بواسطة برنامج العميل، ويحتاج البرنامج من جانب الخادم دائمًا إلى الاستماع إلى رقم المنفذ المحدد للمضيف، في انتظار اتصال العميل. في العميل، نحتاج فقط إلى استخدام مثيلات المقبس، بينما يحتاج الخادم إلى التعامل مع مثيلات ServerSocket ومثيلات المقبس؛ ويستخدم كلاهما OutputStream وInpuStream لإرسال البيانات واستقبالها.
أفضل طريقة لتعلم جزء من المعرفة هي استخدامها. من خلال الملاحظات السابقة، نعرف بالفعل كيفية الحصول على معلومات عنوان المضيف. الآن نستخدم برنامجًا بسيطًا لتعلم برمجة المقبس باستخدام بروتوكول TCP في النقل طبقة.
جانب خادم TCP
في برمجة المقبس، يكون جانب الخادم أكثر تعقيدًا من جانب العميل. تتمثل مهمة الخادم في إنشاء محطة اتصال وانتظار اتصال العميل بشكل سلبي. يتم استخدام المثال التالي لبرنامج من جانب الخادم للاستماع إلى رقم المنفذ الذي تم الحصول عليه من إدخال وحدة التحكم، وإرسال الرسالة التي أرسلها العميل مرة أخرى.
انسخ رمز الكود كما يلي:
importjava.net.*;
importjava.text.MessageFormat;
importjava.io.*;
publicclassTCPEchoServer{
PrivatestaticfinalintBUFSIZE=32;
publicstaticvoidmain(String[]args)throwsIOException{
//TODOAuto-generatedmethodstub
// احصل على رقم المنفذ المراد مراقبته من وحدة التحكم
إذا (args.length!=1)
thrownewIllegalArgumentException("المعلمة (المعلمات):<Port>");
// احصل على رقم المنفذ
intservPort=Integer.parseInt(args[0]);
// إنشاء مثيل لكائن ServerSocket
ServerSocketservSocket=newServerSocket(servPort);
System.out.println(MessageFormat.format("ابدأ الاستماع، رقم المنفذ: {0}"،args[0]));
// إجمالي عدد بايتات البيانات المستلمة الأولية
intrecvMsgSize;
// المخزن المؤقت لتلقي البيانات
byte[]receiveBuf=newbyte[BUFSIZE];
// تكرار التكرار، والاستماع إلى رقم المنفذ، ومعالجة طلبات الاتصال الجديدة
بينما (صحيح) {
// الحظر والانتظار، قم بإنشاء مثيل اتصال جديد في كل مرة يتم فيها تلقي طلب
SwitchclntSocket=servSocket.accept();
// احصل على عنوان المقبس للعميل المتصل
SwitchAddressclientAddress=clntSocket.getRemoteSocketAddress();
// اطبع معلومات عنوان عميل الاتصال
System.out.println("Handlingclientat"+clientAddress);
// الكائن الذي يتلقى البيانات من العميل
InputStreamin=clntSocket.getInputStream();
// الكائن الذي يرسل البيانات إلى العميل
OutputStreamout=clntSocket.getOutputStream();
// بعد قراءة البيانات التي أرسلها العميل، أرسلها إلى العميل
بينما ((recvMsgSize=in.read(receiveBuf))!=-1){
out.write(receiveBuf,0,recvMsgSize);
}
// عندما يغلق العميل الاتصال، أغلق الاتصال
System.out.println("العميل يغلق الاتصال");
clntSocket. Close();
}
}
}
عميل TCP
في برمجة المقبس، يحتاج العميل أولاً إلى الإرسال إلى الخادم، ثم انتظار استجابة الخادم بشكل سلبي. في المثال التالي: نرسل المعلومات إلى الخادم، وننتظر الرسالة التي يرسلها الخادم، ونقوم بطباعتها.
انسخ رمز الكود كما يلي:
importjava.io.*;
importjava.net.Socket;
importjava.net.SocketException;
publicclassTCPEchoClient{
publicstaticvoidmain(String[]args)throwsIOException{
//TODOAuto-generatedmethodstub
// تحديد ما إذا كانت المعلمات المستلمة من وحدة التحكم صحيحة
إذا ((args.length<2)||(args.length>3))
thrownewIllegalArgumentException(
"المعلمة (المعلمات):<Server><Word>[<Port>]]");
//الحصول على عنوان الخادم
Stringserver=args[0];
// احصل على المعلومات التي يجب إرسالها
byte[]data=args[1].getBytes();
// إذا كانت هناك ثلاث معلمات تابعة، فاحصل على رقم المنفذ لإرسال المعلومات. رقم المنفذ الافتراضي هو 8099.
intservPort=(args.length==3)?Integer.parseInt(args[2]):8099;
// إنشاء مثيل مأخذ التوصيل بناءً على عنوان الخادم ورقم المنفذ
Switchsocket=newSocket(server,servPort);
System.out.println("متصل بالخادم...إرسال سلسلة صدى");
// قم بإرجاع دفق الإدخال لهذا المقبس، وهو كائن البيانات المستلم من الخادم
InputStreamin=socket.getInputStream();
// قم بإرجاع دفق الإخراج لهذا المقبس، وهو كائن البيانات المرسل إلى الخادم
OutputStreamout=socket.getOutputStream();
// أرسل البيانات المستلمة من وحدة التحكم إلى الخادم
out.write(data);
// العداد الذي يتلقى البيانات سوف يكتب الإزاحة الأولية للبيانات
inttotalBytesRcvd=0;
// تهيئة العدد الإجمالي للبايتات من البيانات المستلمة
intbytesRcvd;
بينما(totalBytesRcvd<data.length){
// إذا أغلق الخادم الاتصال، فسيتم إرجاع -1. تُرجع طريقة القراءة إجمالي عدد وحدات البايت من البيانات المستلمة.
إذا ((bytesRcvd=in.read(data,totalBytesRcvd,data.length
-totalBytesRcvd))==-1)
thrownewSocketException("تم إغلاق الاتصال بالخادم");
TotalBytesRcvd+=bytesRcvd;
}
// اطبع البيانات المرسلة من الخادم
System.out.println("تم الاستلام:"+newString(data));
// أغلق الاتصال
المقبس. إغلاق ()؛
}
}
قم أولاً بتشغيل الخادم والاستماع على المنفذ 8099:
ثم قم بتشغيل برنامج العميل وأرسل رسالة إلى الخادم:
بالنظر إلى وحدة التحكم من جانب الخادم لدينا مرة أخرى، يمكننا رؤية معلومات عنوان اتصال العميل السابق: