السلام عليكم
سنتكلم اليوم عن كيفية تأمين اتصال وتبادل معلومات بين جهازين باستخدام
Socket and ServerSocket واللذان يمثلان السيرفر والكلاينت
اولا علينا انشاء Class الذي يمثل السيرفر وهو Class الذي سينتظر اتصال الكلاينت
وفي حال اتصاله سيبدأ بتأمين الطلبات حسب البروتوكول الذي ننشأه بينهما
لدينا ثلاث Classes
1- Server : وهو يمثل السيرفر الذي سينتظر اتصال اي كلاينت
وفي حال اتصل اي كلاينت سينشئ له instance من Class الثاني وهو
ClientService والذي سيقوم بخدمة الكلاينت
2- ClientService : كما ذكرنا سيقوم بخدمة الكلاينت باستقبال طلباته وارساله رد عليها
حسب البروتوكول
3- Client : وهو Class الذي سيمثل الكلاينت الذي سيحاول الاتصال بالسيرفر والطلب منه
1 - Server : داخل الكود أدرجت بعض التعليقات البسيطة التي تشرح الكود بشكل مبسط
ولكن سنشرح هنا بعض هذه الخطوات :
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
/*this class extends Thread to generate an instanse from this class
*to every client who connect with this server
*
*/
public class Server {
private ServerSocket server;
private Socket connection;
private ClientService clientService;
public Server()
{
runConnection();
}
public void runConnection()
{
try {
/*
* this ServerSocket take 2 parameter the first parameter the number of port
* who make the connet across
* the second parameter is the numbr of client who can connect with server
*
*/
server = new ServerSocket(1400,100);
while(true) {
/*
* this while wait for client
* when the client connect it will call method waitConnection to accept the client and generate thread
* to this client
*/
waitConnection();
}//End While
}//End Try
catch(IOException iOE)
{
/*
* when an error happend this message will be
* show to the user
*/
JOptionPane.showMessageDialog(null, "An Error happend when the program was waiting for clints connection"
,"restart this program",JOptionPane.ERROR_MESSAGE);
}
}//End runConnection Method
public void waitConnection() throws IOException
{
/*
* when the client connect with this server it need to
* accept the server to this client
* than generate thread for this client
*/
connection = server.accept();
clientService = new ClientService(connection);
clientService.start();
/*
* when thread generated we call run method from clientService2
* to run start method onclientService2
*
*
*/
}//End waitConnection Method
public static void main(String i[])
{
Server server = new Server();
}
}سنبدأ من runConnection method
الذي كما نلاحظ بالكود فهو يعرف serverSocket
التي تأخذ two parameters الأول 1400 وهو يمثل رقم البورت الذي سينتظر السيرفر اتصال الكلاينت عليه
والباراميتر الثاني 100 والذي يمثل عدد الكلاينتات الذي يسمح لهم بالاتصال بهذا السيرفر
بعدها أعلنا حلقة لا نهائية والتي في كل مرة تستدعي waitConnection method
والذي سيتم في داخله قبول الكلاينت اولا ومن ثم انشاء
instance من Class ClientService ليتم خدمة الكلاينت ومن ثم ينتهي عمل method
لتعود الحلقة الى الدوران منتظرة كلاينت آخر
waitConnection method : ضمن هذا method وكما نلاحظ استدعء method accept()
من عند ServerSocket class والتي ستبحث اذا كان هناك اي (client)socket تحاول الاتصال بالسيرفر
ففي حال هناك كلاينت يتصل سيتم قبوله عن طريق هذه method
والتي ستعيد لنا Object من نوع Socket والذي يمثل اتصال هذا الكلاينت
والذي عن طريقه سيتم تبادل المعلومات بين السيرفر والكلاينت
بعد الحصول على هذا ال Object ننشئ instance من Class ClientService
والذي هو extends Thread أي انه سيتم انشاء Thread خاصة فقط لهذا الكلاينت لتتم خدمته
اي استقبال وارسال المعلومات
ومن ثم نستدعي start() من هذا Class التي بدورها ستسدعي method run()
عند Class ClientService
Class الثاني
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.Calendar;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class ClientService extends Thread
{
private ObjectInputStream inputObject;
/*
* ObjectInputStream it use to read anything who wrote from the client
* like Object or int or etc...
*
*/
private ObjectOutputStream outputObject;
/*
* ObjectOutputStream it use to write anything to the client
* like Object or int or etc...
*/
private Socket connection;
public ClientService()
{
}
public ClientService(Socket connect)
{
connection = connect;
}
public void run()
{
try {
getStreams();
/*
* when the client connet we must get the stream who help
* as to read and write from and to the client
*
*/
processOrders();
/*
* this method
* will help us to process all the client request
*
*
*/
}
catch(IOException iO)
{
iO.printStackTrace();
}
}//End run Method
public void getStreams()throws IOException
{
outputObject = new ObjectOutputStream(connection.getOutputStream());
outputObject.flush();
inputObject = new ObjectInputStream(connection.getInputStream());
/*
* when we got the stream from the connection we can
* read and write from and to the client
*
*/
}//End getStreams Method
public void processOrders()
{
/*
* here we can process all the client requests
*
*/
try {
do{
System.out.println("Message Received is : "+inputObject.readObject().toString());
}while(true);
}
catch(Exception iO)
{
/*
* if there an error happend when the server
* is reading client request
*/
iO.printStackTrace();
}
}//End processOrders
public void writeToTheClient() throws Exception
{
/*
* here we can write anything to the client
* by the outputObject it helps us to
* to write to the client look to the example down
*/
outputObject.write(3);
/*
* here we write int to the client
*/
outputObject.writeObject(new Object());
/*
* here we write an Object to the client
*/
outputObject.write(new byte[8]);
/*
* here we write byte[] array to the client
*/
outputObject.writeByte(2);
/*
* here we write byte to the client
*/
}
}سنبدأ الشرح من method run()
والتي تستدعي two methods
getStream() : وهذا method نستخدمه للحصول على Classes ObjectInputStream & ObjectOutputStream والذان سيتم ارسال واستقبال الطلبات عن طريقهم
وكما تلاحظون حصلنا على Classes عن طريق ال Socket التي حصلنا عليها من method accept
ضمن Class ال Server والتي مررناها ضمن ClientService constructor
processOrders() : هذه method سيتم فيها استقبال طلبات الكلاينت
هناك حلقة لا نهائية والتي في كل مرة تفحص اذا كان هناك اي طلب قد ارسل من الكلاينت
طبعا عن طريق Class ObjectInputStream الذي حصلنا عليه سابقا
ضمن هذه الحلقة سيتم قراءة ما يكتبه الكلاينت وهنا تستطيع ان تقرأ ما تريد
Object or int or byte etc.. وهذا يعتمد على البروتوكول الذي وضعته انت بين الكلاينت والسيرفر
writeToTheClient() : هذا method عن طريقه نستطيع الكتابة الى الكلاينت
عن طريق ObjectOutputStream الذي حصلنا عليه سابقا
وهنا نستطيع ان نكتب اي شيء للكلاينت مثل
Object int byte etc…
وبهذا يكون قد انتهى هذا Class
Class الثالث :
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class Client
{
private ObjectOutputStream output;
private ObjectInputStream input;
private int order;
private Socket client;
public Client(String ip)
{
/*
* here you must put the server ip
* who want to connect with
*/
connect(ip);
}
public void connect(String ipAddress)
{
/*
* this method use to connect with
* the server by using the server ip address and the port
* that the server wait on
*/
try {
/*
* the socket takes 2 parameters
* the first parameter is server ip address
* the second parameter is the port number that the server wait on
* to recieve client requests
*/
client = new Socket( ipAddress , 1400 );
getStreams();
/*
* when the client connect to the server
* we must get the ObjectOutputStream and ObjectInputStream
* to read and write from and to the server
*/
sendOrder();
System.out.println("message was sent");
}
catch(IOException iO)
{
/*
* this message will show when an error happend while
* the client is trying to connect with server
*/
JOptionPane.showMessageDialog(null, "Unable to connect with this IP Address"
,"Invalid IP",JOptionPane.ERROR_MESSAGE);
System.exit(0);
/*
* it use to end the program
*/
}
}//End connect Method
public void getStreams()
{
try {
/*
* here we get the input and output stream from the socket
* to be able to read and write to and from the server
*/
output = new ObjectOutputStream(client.getOutputStream());
output.flush();
input = new ObjectInputStream(client.getInputStream());
}
catch(IOException iO)
{
/*
* this message will show when an error happend while
* the client is trying to get the stream from the socket
*/
JOptionPane.showMessageDialog(null, "Unable to get Stream from this IP Address"
,"Connection Lost",JOptionPane.ERROR_MESSAGE);
}
}//End getStreams Method
public void sendOrder()
{
try {
/*
* here we can write anything to the server
* like Object or int or byte or char etc...
*/
while(true){
String message = JOptionPane.showInputDialog("Insert your message");
if(message.equals(null))
message = "no message";
output.writeObject(message);
output.flush();
System.out.println("Message : "+message+" :: was sent");
}
}
catch(Exception iOE)
{
/*
* this message will show when an error happend while
* the client is trying to send somthing to the server
*/
JOptionPane.showMessageDialog(null, "Unable to send any order to this IP Address Please try to Open new Connection"
,"Connection Lost",JOptionPane.ERROR_MESSAGE);
}
}//End sendOrder Method
public static void main(String h[] )
{
Client client = new Client("127.0.0.1");
}
}سنبدأ الشرح من connect method
الذي يأخذ one parameter وهو يمثل Server IP
ضمن هذا method ننشئ Socket والتي تأخذ one parameter وهو Server IP
الذي سيتصل الكلاينت به
اذا كان السيرفر متصل سنحصل هنا على الاتصال وبعدها سيتم استدعاء method getStreams()
والتي سنحصل منها على two classes وهما ObjectInputStream & ObjectOutputStream
والذان سنستخدمهما للقراءة والكتابه من والى السيرفر
والذي تم الاتصال معه
عند انتهاء هذا method سيكون الاتصال قد تحقق بين السيرفر والكلاينت وهنا سيتم ارسال واستقبال الطلبات
وذلك يعتمد كما قلنا سابقا على البروتوكول الذي تعلنها بينهما
مع هذا الموضوع هناك ملف مرفق بامتداد zip
ويحوي على ثلاث Classesوهي تمثل ارسال رسالة الى السرفر من الكلاينت ليتم عرضها
فقط شغل Class السيرفر ومن ثم Class الكلاينت وارسل الرسايل
ملا حظة : في مثالنا هذا نحن نرسل فقط String عندما تصل الى السيرفر سيقوم بطباعتها
أرجوا ان أكون قد وفقت بالشرح

