تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
الاتصال عن بعد من خلال الجافا .. Chat
#1
بسم الله الرحمن الرحيم
تعتبر لغة الجافا من اقوي اللغات في عمليات الاتصال الشبكي و التحكم عن بعد ..لذا ساتحدث اليوم عن احدي تطبيقات الاتصال عن بعد من خلال الجافا وهو شات شبكي بسيط و لكنه يعبر عن مدي قوة و مرونة لغة الجافا في هذا النوع من التطبيقات ..
يتكون المثال من برنامجي عميل و سيرفر ..يتم الاتصال بينهما باستخدام Socket و الذي سيتم التعامل معه مباشرة من خلال الكود ..
سيعتمد الاتصال الشبكي عبر السوكيت علي رقم المنفذ Port و رقم ال IP ..
ما هو Socket :
وهي اداة تستخدم لتحقيق عملية الاتصال المتبادل بين جهازين احدهما عميل و الآخر سيرفر او بين مجموعة من الاجهزة و تعتمد في عملية الاتصال علي رقم المنفذ الخاص ببروتوكول الاتصال الشبكي Port For TCP ,UDP Connection ..و الذي يجب ان تكون قيمته اعلي من 1023 حيث ان نظام التشغيل يشتمل علي 65535 منفذ و المنافذ الخاصة بنظام التشغيل ويندوز تبدأ من 0 و تنتهي عند 1023 ..
يفضل ان تكون قيم منافذ الاتصال الشبكي من 2048 الي 5002 لانها الاسرع في الاتصال ..

[ATTACH=CONFIG]83[/ATTACH]


[ATTACH=CONFIG]84[/ATTACH]


اولا : شاشة العميل و هي علي النحو التالي ..

[ATTACH=CONFIG]82[/ATTACH]

تتكون من .. jTextArea , 3 jTextField , 2 jButton , 3 jLabel ..

المكتبات التي يعتمد عليها شاشة العميل :

كود :
import java.io.IOException;
import java.net.InetAddress;  
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;  
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;  
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;  
import java.util.LinkedList;  
import java.util.Set;

تفسير عام لبعض المكتبات :
----------------------------

[COLOR="#FFA07A"]java.io.IOException : تستخدم للتعبير عن عمليات الاستثنائات التي تنتجها عمليات I / O فشل أو توقف.
java.net.InetAddress : وهي المكتبة التي تمثل الرقم الخاص ببروتوكول الانترنت TCP / IP
java.net.InetSocketAddress : تمثل هذه المكتبة عنوان بروتوكول الاتصال + رقم منفذ الاتصال
java.nio.ByteBuffer : هذه المكتبة تمثل مجموعة فئات للتعامل مع Byte مثل :get و compacting
java.nio.channels.SocketChannel : يتم من خلالها تحديد قناة الاتضال الخاصة بالسوكيت
java.nio.charset.Charset : تستخدم في عمليات فك التشفير و الترميز لاساليب التشفير من unicode و ascii
java.nio.charset.CharsetDecoder : تستدم لتحويل سلاسل البيانات المكونة من سلاسل unicode و المكونة من 16 بت الي binary
java.util.LinkedList : تستخدم بوجه عام في عملية ترتيب العناصر في القوائم من خلال متابع احداث الاتصال
java.util.Set : تتضمن علي عمليات الاعلان عن غيرها من الفئات الموروثة و عمليات البحث خلال المكتبات و hashcode
[/COLOR]


في الكلاس الرئيسي لشاشة العميل نعرف المتغيرات التالية :

كود :
private Client ChatClient;
  private ReadThread myRead=new ReadThread();
  private String ServerName;
  private String UserName;

نأتي الي اهم جزئ في برنامج العميل و هو كلاس [COLOR="#0000FF"]Client :[/COLOR]

تفسير الكلاس :
كود :
int PORT=5002;

متغير بقيمة رقم البورت ..

كود :
private LinkedList Clients;

متغير LinkedList و هو المسئول عن ترتيب العناصر في شكل قائمة متصلة باحداث الارسال و الاستقبال النصي ..

كود :
private ByteBuffer ReadBuffer

متغير متصل بالمتغير السابق و يستخدم في عملية متابع النصوص المستقبلة و ارفاقها بالمتغير السابق ..

كود :
private ByteBuffer writeBuffer;

عكس المتغير السابق و يستخدم في عملية الكتابة ..

كود :
private SocketChannel SChan;

متغير لتحديد قناة الاتصال ..

كود :
private CharsetDecoder asciiDecoder;

متغير يستخدم في عمليات تشفير و فك تشفير رموز اسكي ..

كود :
public Client() {
            Clients=new LinkedList();
            ReadBuffer=ByteBuffer.allocateDirect(300);
            writeBuffer=ByteBuffer.allocateDirect(300);
            asciiDecoder = Charset.forName( "US-ASCII").newDecoder();

تستخدم هذه الدالة في عمليات القرائة و الكتابة ضمن القائمة jTextArea و في تحديد نوع تشفير اسكي و هو US-ASCII ..

كود :
public void Connect(String hostname) {
            try {
                ReadSelector = Selector.open();
                InetAddress addr = InetAddress.getByName(hostname);
                SChan = SocketChannel.open(new InetSocketAddress(addr, PORT));
                SChan.configureBlocking(false);          
                SChan.register(ReadSelector, SelectionKey.OP_READ, new StringBuffer());
            }    
            catch (Exception e) {
            }
        }


يتم من خلال هذه الدالة تحديد جهة الاتصال التي سيتم الاتضال بالسيرفر الخاص بها ان وجد من خلال selector و يتم ايضا التحقق من قناة الاتصال لاتمام عملية الاتصال و الحصول علي اسم الجهاز الخادم ..

كود :
public void run() {
            ServerName=Server.getText();
            System.out.println(ServerName);
            UserName=User.getText();          
            Connect(ServerName);
            myRead.start();
            while (true) {              
                ReadMassage();            
                try {
                    Thread.sleep(30);
                } catch (InterruptedException ie){
                }
            }          
        }

يتم من خلال هذه الدالة الحصول علي اسم الخادم و طباعة الاسم ضمن عناصر القائمة و هكذا بالنسبة لاسم المستخدم و تهيئة عملية القرائة من الخادم فان كان هناك نص مرسل فستتم عملية القرائة و طباعة النص المستقبل ..

كود :
public void SendMassage(String messg) {
            prepareBuffer(UserName+" says: "+messg);
            channelWrite(SChan);
        }

يتم من خلالها ارسال النص المكتوب في مربع النص الي الخادم + امر بارسال رقم الاي بي من خلال قناة الاتصال ..

كود :
public void prepareBuffer(String massg) {
            writeBuffer.clear();
            writeBuffer.put(massg.getBytes());
            writeBuffer.putChar('\n');
            writeBuffer.flip();
        }

مرتبطة بالدالة السابقة و يتم فيها تسلسل احداث عملية الكتابة ..
حيث عند بدئ عملية الارسال يتم حذف الرسائل السابقة المسجلة في ذاكرة البرنامج ..ثم ضع الرسالة الجديدة في الذاكرة ..ثم نفذ الامر n/ ثم ارسل من خلال الدالة sendmessage ..

كود :
public void channelWrite(SocketChannel client) {
            long num=0;
            long len=writeBuffer.remaining();
            while(num!=len) {
                try {
                    num+=SChan.write(writeBuffer);          
                    Thread.sleep(5);
                } catch (IOException ex) {
                    ex.printStackTrace();
                } catch(InterruptedException ex) {        
                }      
            }
            writeBuffer.rewind();
        }

يتم من خلالها ارسال طلب بروتوكول الاتصال الشبكي من خلال رقم قناة الاتصال ..

كود :
public void ReadMassage() {    
            try {        
                ReadSelector.selectNow();            
                Set readyKeys = ReadSelector.selectedKeys();                
                Iterator i = readyKeys.iterator();                
                while (i.hasNext()) {                
                    SelectionKey key = (SelectionKey) i.next();
                    i.remove();
                    SocketChannel channel = (SocketChannel) key.channel();
                    ReadBuffer.clear();                                    
                    long nbytes = channel.read(ReadBuffer);              
                    if (nbytes == -1) {
                        textArea1.append("You logged out !\n");
                        channel.close();
                    } else {                      
                        StringBuffer sb = (StringBuffer)key.attachment();                        
                        ReadBuffer.flip( );
                        String str = asciiDecoder.decode( ReadBuffer).toString( );
                        sb.append( str );
                        ReadBuffer.clear( );                                            
                        String line = sb.toString();
                        if ((line.indexOf("\n") != -1) || (line.indexOf("\r") != -1)) {
                            line = line.trim();
                            textArea1.append("> "+ line);
                            textArea1.append(""+'\n');
                            sb.delete(0,sb.length());
                        }
                    }
                }
            } catch (IOException ioe) {
            } catch (Exception e) {
            }
        }
    }

يتم الاعتماد علي هذه الدالة بشكل كلي في عملية استقبال النص المرسل من الخادم ..

كود :
class ReadThread extends Thread {
        public void run() {
            ChatClient.ReadMassage();
        }
    }

يستخدم هذا الكلاس و الذي يحتوي علي thread في عملية مراقبة مايتم ارسالة من الجهاز الخادم ..(وتحويلة الي عمليات فيك التشفير النصي ..التفنيط ثم القرائة .. ثم التحويل من الذاكرة ..ثم ادراج نص الرسالة في القائمة) وكل هذا من خلال الكلاس الاول ..

في حدث الضغط علي زر Send :

كود :
if (ChatClient != null)
  {
System.out.println(UserText.getText());
ChatClient.SendMassage(UserText.getText());
  }
}

في حدث الضغط علي زر connect :

كود :
ChatClient=new Client();
       ChatClient.start();

بخصوص ال Tread و ال Timer سيتم الشرح المرة القادمة بأذن الله ..Smile

ثانيا : شاشة الخادم :

[ATTACH=CONFIG]85[/ATTACH]

وتتكون من jTextArea و jLabel و jTextField و jButton ..

المكتبات التي يعتمد عليها شاشة الخادم ..

هي نفس المكتبات التي يعتمد عليها العميل بالاضافة الي هذه المكتبة :

كود :
import java.nio.channels.ServerSocketChannel;

لتحديد قناة الاتصال الخاصة بالخادم و هي قناة اتصال واحدة للخادم والعميل ..

نعرف المتغيرات التالية في الفئة الرئيسية للبرنامج :

كود :
private server ChatServer;
    private InetAddress ServerAddress ;

قمنا بتعريف خادم ChatServer و قمنا بتعريف عنوان الخادم و هو مرتبط بعنوان قناة الاتصال و عنوان بروتوكول الاتصال ip ..

الكلاس المسئول عن احداث عمل الخادم :

كود :
public class server extends Thread {
        private static final int PORT=5002;
        private LinkedList Clients;
        private ByteBuffer ReadBuffer;
        private ByteBuffer WriteBuffer;
        public  ServerSocketChannel SSChan;
        private Selector ReaderSelector;
        private CharsetDecoder asciiDecoder;
        
        public server() {
            Clients=new LinkedList();
            ReadBuffer=ByteBuffer.allocateDirect(300);
            WriteBuffer=ByteBuffer.allocateDirect(300);
            asciiDecoder = Charset.forName( "US-ASCII").newDecoder();
        }
        
        public void InitServer() {
            try {
                SSChan=ServerSocketChannel.open();
                SSChan.configureBlocking(false);
                ServerAddress=InetAddress.getLocalHost();
                System.out.println(ServerAddress.toString());  
                SSChan.socket().bind(new InetSocketAddress(ServerAddress,PORT));
                ReaderSelector=Selector.open();
                ChatBox.setText(ServerAddress.getHostName()+" .. Chat_Server Started... \n");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        
        public void run() {
            InitServer();
            while(true) {
                acceptNewConnection();
                ReadMassage();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }                
            }
        }
        
        public void acceptNewConnection() {
            SocketChannel newClient;
            try {
                while ((newClient = SSChan.accept()) != null) {
                    ChatServer.addClient(newClient);
                    sendBroadcastMessage(newClient,"Login from: " +newClient.socket().getInetAddress());
                    SendMassage(newClient,ServerAddress.getHostName()+" Cchat_Server .. welcome!\n Note :To exit" +
                    " From Server Write 'quit' .\n");
                }  
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        public void addClient(SocketChannel newClient) {
            Clients.add(newClient);
            try {
                newClient.configureBlocking(false);
                newClient.register(ReaderSelector,SelectionKey.OP_READ,new StringBuffer());    
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        
        public void SendMassage(SocketChannel client ,String messg) {
            prepareBuffer(messg);
            channelWrite(client);
        }
        
        public void SendMassage(String massg) {
            if(Clients.size()>0) {
                for(int i=0;i<Clients.size();i++) {
                    SocketChannel client=(SocketChannel)Clients.get(i);
                    SendMassage(client,massg);
                }
            }
        }
          
        public void prepareBuffer(String massg) {
            WriteBuffer.clear();
            WriteBuffer.put(massg.getBytes());
            WriteBuffer.putChar('\n');
            WriteBuffer.flip();
        }
        
        public void channelWrite(SocketChannel client) {
            long num=0;
            long len=WriteBuffer.remaining();
            while(num!=len) {
                try {
                    num+=client.write(WriteBuffer);
                    
                    Thread.sleep(5);
                } catch (IOException ex) {
                    ex.printStackTrace();
                } catch(InterruptedException ex) {        
                }
            }
            WriteBuffer.rewind();
        }
        
        public void sendBroadcastMessage(SocketChannel client,String mesg) {
            prepareBuffer(mesg);
            Iterator i = Clients.iterator();
            while (i.hasNext()) {
                SocketChannel channel = (SocketChannel)i.next();
                if (channel != client) {
                    channelWrite(channel);
                }
            }
        }
        public void ReadMassage() {
            try {          
                ReaderSelector.selectNow();
                Set readkeys=ReaderSelector.selectedKeys();
                Iterator iter=readkeys.iterator();
                while(iter.hasNext()) {
                    SelectionKey key=(SelectionKey) iter.next();
                    iter.remove();                  
                    SocketChannel client=(SocketChannel)key.channel();
                    ReadBuffer.clear();                
                    long num=client.read(ReadBuffer);                
                    if(num==-1) {
                        client.close();
                        Clients.remove(client);
                        sendBroadcastMessage(client,"logout: " +
                                client.socket().getInetAddress());                      
                    } else {                      
                        StringBuffer str=(StringBuffer)key.attachment();
                        ReadBuffer.flip();
                        String data= asciiDecoder.decode(ReadBuffer).toString();
                        ReadBuffer.clear();
                        str.append(data);
                        String line = str.toString();
                        if ((line.indexOf("\n") != -1) || (line.indexOf("\r") != -1)) {
                            line = line.trim();
                            System.out.println(line);
                            if (line.endsWith("quit")) {
                                client.close();
                                Clients.remove(client);
                                ChatBox.append("Logout: " + client.socket().getInetAddress());
                                sendBroadcastMessage(client,"Logout: "
                                + client.socket().getInetAddress());
                                ChatBox.append(""+'\n');
                            } else {
                                ChatBox.append(client.socket().getInetAddress() + ": " + line);
                                sendBroadcastMessage(client,client.socket().getInetAddress()
                                + ": " + line);
                                ChatBox.append(""+'\n');
                                str.delete(0,str.length());
                            }
                        }
                    }
                }    
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

تفسير الكلاس :

كود :
ublic void InitServer() {
            try {
                SSChan=ServerSocketChannel.open();
                SSChan.configureBlocking(false);
                ServerAddress=InetAddress.getLocalHost();
                System.out.println(ServerAddress.toString());  
                SSChan.socket().bind(new InetSocketAddress(ServerAddress,PORT));
                ReaderSelector=Selector.open();
                ChatBox.setText(ServerAddress.getHostName()+" .. Chat_Server Started... \n");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }


يتم من خلال هذه الدالة تهيئة الخادم ..من خلال فتح قناة الاتصال مع العميل و الحصول علي عنوان بروتوكول العميل ..وفتح محدد ااتصال بالعميل selector و طباعة عنوان بروتوكول العميل + جملة ("chat_server started") ...

كود :
public void acceptNewConnection() {
            SocketChannel newClient;
            try {
                while ((newClient = SSChan.accept()) != null) {
                    ChatServer.addClient(newClient);
                    sendBroadcastMessage(newClient,"Login from: " +newClient.socket().getInetAddress());
                    SendMassage(newClient,ServerAddress.getHostName()+" Cchat_Server .. welcome!\n Note :To exit" +
                    " From Server Write 'quit' .\n");
                }  
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


تستخدم هذه الدالة للتحقق من عمليات الاتصال من رقم المنفذ و قناة الاتصال فاذا تتطابقت الشروط فسيتم ارسال عبارة الي العميل تعبر عن نجاح عملية الاتصال وهي etc ...welcome!\n

كود :
public void prepareBuffer(String massg) {
            WriteBuffer.clear();
            WriteBuffer.put(massg.getBytes());
            WriteBuffer.putChar('\n');
            WriteBuffer.flip();
        }

كود :
public void SendMassage(SocketChannel client ,String messg) {
            prepareBuffer(messg);
            channelWrite(client);
        }

كما حدث بالضبط في الدالة SendMessage و PrepareBuffer الخاصة ببرنامج العميل من كلاس Client

كود :
public void sendBroadcastMessage(SocketChannel client,String mesg) {
            prepareBuffer(mesg);
            Iterator i = Clients.iterator();
            while (i.hasNext()) {
                SocketChannel channel = (SocketChannel)i.next();
                if (channel != client) {
                    channelWrite(channel);
                }
            }
        }

تستخدم هذه الدالة لارسال رسالة اعلام الي العميل بأن السرفر جاهز لاستقبال الرسائل ..

في حدث WindowOpened للفورم نكتب هذا الكود :

كود :
ChatServer=new server();
                ChatServer.start();

في حدث الضغط علي زر Send :

كود :
ChatServer.SendMassage(ServerAddress.getHostName()+" < Server > "+UserText.getText());


رابط تحميل المثال :

[ATTACH]87[/ATTACH]

[COLOR="#FFA07A"]لانشاء البرنامج بالكود :
قم فقط بانشاء ملف كلاس لكل منهما ..بحيث يكون اسم الملف بنفس اسم الكلاس الرئيسي في كل من البرنامجين ..وضع الكود كما هو ..[/COLOR]
شاشة العميل :

كود :
package clientchat;

import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;


public class myFrame extends JFrame{
    
    /** Creates a new instance of myFrame */
    private JTextArea ChatBox=new JTextArea(10,45);
    private JScrollPane myChatHistory=new JScrollPane(ChatBox,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    private JTextArea UserText = new JTextArea(5,40);
    private JScrollPane myUserHistory=new JScrollPane(UserText,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    private JButton Send = new JButton("Send");
    private JButton Start = new JButton("Connect");
    private Client ChatClient;
    private ReadThread myRead=new ReadThread();
    private JTextField Server=new JTextField(20);
    private JLabel myLabel=new JLabel("Server Name :");
    private JTextField User=new JTextField(10);
    private String ServerName;
    private String UserName;
    
    
    public myFrame() {
        setResizable(false);
        setTitle("Client");
        setSize(560,400);
        Container cp=getContentPane();
        cp.setLayout(new FlowLayout());
        cp.add(new JLabel("Chat History"));
        cp.add(myChatHistory);
        cp.add(new JLabel("Chat Box : "));
        cp.add(myUserHistory);
        cp.add(Send);
        cp.add(Start);
        cp.add(myLabel);
        cp.add(Server);
        cp.add(User);
        Send.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(ChatClient!=null) {
                    
                    System.out.println(UserText.getText());
                    ChatClient.SendMassage(UserText.getText());
                }
            }
        });
        Start.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ChatClient=new Client();
                ChatClient.start();
            }
        });
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        
        
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        new myFrame();
    }
    
    
    public class Client extends Thread {
        private static final int PORT=9999;
        private LinkedList Clients;
        private ByteBuffer ReadBuffer;
        private ByteBuffer writeBuffer;
        private SocketChannel SChan;
        private Selector ReadSelector;
        private CharsetDecoder asciiDecoder;
        
        public Client() {
            Clients=new LinkedList();
            ReadBuffer=ByteBuffer.allocateDirect(300);
            writeBuffer=ByteBuffer.allocateDirect(300);
            asciiDecoder = Charset.forName( "US-ASCII").newDecoder();
        }
        
        public void run() {
            
            ServerName=Server.getText();
            System.out.println(ServerName);
            UserName=User.getText();
            
            Connect(ServerName);
            myRead.start();
            while (true) {
                
                ReadMassage();
                
                try {
                    Thread.sleep(30);
                } catch (InterruptedException ie){
                }
            }
            
        }
        public void Connect(String hostname) {
            try {
                ReadSelector = Selector.open();
                InetAddress addr = InetAddress.getByName(hostname);
                SChan = SocketChannel.open(new InetSocketAddress(addr, PORT));
                SChan.configureBlocking(false);
                
                SChan.register(ReadSelector, SelectionKey.OP_READ, new StringBuffer());
            }
            
            catch (Exception e) {
            }
        }
        public void SendMassage(String messg) {
            prepareBuffer(UserName+" says: "+messg);
            channelWrite(SChan);
        }
        
        
        public void prepareBuffer(String massg) {
            writeBuffer.clear();
            writeBuffer.put(massg.getBytes());
            writeBuffer.putChar('\n');
            writeBuffer.flip();
        }
        
        public void channelWrite(SocketChannel client) {
            long num=0;
            long len=writeBuffer.remaining();
            while(num!=len) {
                try {
                    num+=SChan.write(writeBuffer);
                    
                    Thread.sleep(5);
                } catch (IOException ex) {
                    ex.printStackTrace();
                } catch(InterruptedException ex) {
                    
                }
                
            }
            writeBuffer.rewind();
        }
        
        public void ReadMassage() {
            
            try {
                
                ReadSelector.selectNow();
                
                Set readyKeys = ReadSelector.selectedKeys();
                
                Iterator i = readyKeys.iterator();
                
                while (i.hasNext()) {
                    
                    SelectionKey key = (SelectionKey) i.next();
                    i.remove();
                    SocketChannel channel = (SocketChannel) key.channel();
                    ReadBuffer.clear();
                    
                    
                    long nbytes = channel.read(ReadBuffer);
                    
                    if (nbytes == -1) {
                        ChatBox.append("You logged out !\n");
                        channel.close();
                    } else {
                        
                        StringBuffer sb = (StringBuffer)key.attachment();
                        
                        ReadBuffer.flip( );
                        String str = asciiDecoder.decode( ReadBuffer).toString( );
                        sb.append( str );
                        ReadBuffer.clear( );
                        
                        
                        String line = sb.toString();
                        if ((line.indexOf("\n") != -1) || (line.indexOf("\r") != -1)) {
                            line = line.trim();
                            
                            ChatBox.append("> "+ line);
                            ChatBox.append(""+'\n');
                            sb.delete(0,sb.length());
                        }
                    }
                }
            } catch (IOException ioe) {
            } catch (Exception e) {
            }
        }
    }
    class ReadThread extends Thread {
        public void run() {
            ChatClient.ReadMassage();
        }
    }
}

شاشة الخادم :

كود :
package serverchat;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


public class myFrame extends JFrame{
    
    /** Creates a new instance of myFrame */
    private JTextArea ChatBox=new JTextArea(10,45);
    private JScrollPane myChatHistory=new JScrollPane(ChatBox,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    private JTextArea UserText = new JTextArea(5,40);
    private JScrollPane myUserHistory=new JScrollPane(UserText,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    private JButton Send = new JButton("Send");
    private JButton Start = new JButton("Start Server!");
    private server ChatServer;
    private InetAddress ServerAddress ;
    
    public myFrame() {
        setTitle("Server");
        setSize(560,400);
        Container cp=getContentPane();
        cp.setLayout(new FlowLayout());
        cp.add(new JLabel("Server History"));
        cp.add(myChatHistory);
        cp.add(new JLabel("Chat Box : "));
        cp.add(myUserHistory);
        cp.add(Send);
        cp.add(Start);
        
        
        
        Start.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                
                ChatServer=new server();
                ChatServer.start();
                
            }
        });
        Send.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ChatServer.SendMassage(ServerAddress.getHostName()+" < Server > "+UserText.getText());
            }
        });
        
        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        
        
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        new myFrame();
    }
    
    
    public class server extends Thread {
        private static final int PORT=9999;
        private LinkedList Clients;
        private ByteBuffer ReadBuffer;
        private ByteBuffer WriteBuffer;
        public  ServerSocketChannel SSChan;
        private Selector ReaderSelector;
        private CharsetDecoder asciiDecoder;
        
        
        public server() {
            Clients=new LinkedList();
            ReadBuffer=ByteBuffer.allocateDirect(300);
            WriteBuffer=ByteBuffer.allocateDirect(300);
            asciiDecoder = Charset.forName( "US-ASCII").newDecoder();
        }
        
        public void InitServer() {
            try {
                SSChan=ServerSocketChannel.open();
                SSChan.configureBlocking(false);
                ServerAddress=InetAddress.getLocalHost();
                System.out.println(ServerAddress.toString());
                
                SSChan.socket().bind(new InetSocketAddress(ServerAddress,PORT));
                
                ReaderSelector=Selector.open();
                ChatBox.setText(ServerAddress.getHostName()+"<Server> Started. \n");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        public void run() {
            InitServer();
            
            while(true) {
                acceptNewConnection();
                
                ReadMassage();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                
                
            }
        }
        
        public void acceptNewConnection() {
            SocketChannel newClient;
            try {
                
                while ((newClient = SSChan.accept()) != null) {
                    ChatServer.addClient(newClient);
                    
                    sendBroadcastMessage(newClient,"Login from: " +newClient.socket().getInetAddress());
                    
                    SendMassage(newClient,ServerAddress.getHostName()+"<server> welcome you !\n Note :To exit" +
                            " from server write 'quit' .\n");
                }
                
            } catch (IOException e) {
                e.printStackTrace();
            }
            
        }
        
        public void addClient(SocketChannel newClient) {
            Clients.add(newClient);
            try {
                newClient.configureBlocking(false);
                newClient.register(ReaderSelector,SelectionKey.OP_READ,new StringBuffer());
                
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        
        public void SendMassage(SocketChannel client ,String messg) {
            prepareBuffer(messg);
            channelWrite(client);
        }
        public void SendMassage(String massg) {
            if(Clients.size()>0) {
                for(int i=0;i<Clients.size();i++) {
                    SocketChannel client=(SocketChannel)Clients.get(i);
                    SendMassage(client,massg);
                }
            }
        }
        
        
        public void prepareBuffer(String massg) {
            WriteBuffer.clear();
            WriteBuffer.put(massg.getBytes());
            WriteBuffer.putChar('\n');
            WriteBuffer.flip();
        }
        
        public void channelWrite(SocketChannel client) {
            long num=0;
            long len=WriteBuffer.remaining();
            while(num!=len) {
                try {
                    num+=client.write(WriteBuffer);
                    
                    Thread.sleep(5);
                } catch (IOException ex) {
                    ex.printStackTrace();
                } catch(InterruptedException ex) {
                    
                }
            }
            WriteBuffer.rewind();
        }
        
        public void sendBroadcastMessage(SocketChannel client,String mesg) {
            prepareBuffer(mesg);
            Iterator i = Clients.iterator();
            while (i.hasNext()) {
                SocketChannel channel = (SocketChannel)i.next();
                if (channel != client) {
                    channelWrite(channel);
                }
            }
        }
        public void ReadMassage() {
            try {
                
                ReaderSelector.selectNow();
                Set readkeys=ReaderSelector.selectedKeys();
                Iterator iter=readkeys.iterator();
                while(iter.hasNext()) {
                    SelectionKey key=(SelectionKey) iter.next();
                    iter.remove();
                    
                    SocketChannel client=(SocketChannel)key.channel();
                    ReadBuffer.clear();
                    
                    long num=client.read(ReadBuffer);
                    
                    if(num==-1) {
                        client.close();
                        Clients.remove(client);
                        sendBroadcastMessage(client,"logout: " +
                                client.socket().getInetAddress());
                        
                    } else {
                        
                        StringBuffer str=(StringBuffer)key.attachment();
                        ReadBuffer.flip();
                        String data= asciiDecoder.decode(ReadBuffer).toString();
                        ReadBuffer.clear();
                        
                        str.append(data);
                        
                        String line = str.toString();
                        if ((line.indexOf("\n") != -1) || (line.indexOf("\r") != -1)) {
                            line = line.trim();
                            System.out.println(line);
                            
                            if (line.endsWith("quit")) {
                                client.close();
                                
                                Clients.remove(client);
                                
                                ChatBox.append("Logout: " + client.socket().getInetAddress());
                                
                                sendBroadcastMessage(client,"Logout: "
                                        + client.socket().getInetAddress());
                                ChatBox.append(""+'\n');
                            } else {
                                ChatBox.append(client.socket().getInetAddress() + ": " + line);
                                
                                sendBroadcastMessage(client,client.socket().getInetAddress()
                                + ": " + line);
                                
                                ChatBox.append(""+'\n');
                                
                                str.delete(0,str.length());
                            }
                        }
                    }
                }
                
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    
}


بواسطة الأخ Friendassist


الملفات المرفقة صورة/صور
               

.rar   chat java.rar (الحجم : 55.96 ك ب / التحميلات : 212)
رابط قناتي على اليوتيوب :
https://www.youtube.com/user/OsamaAhmadGalal
رابط حساب الفيسبوك :

https://www.facebook.com/P.Osama.Ahmad.Galal
رابط حساب التويتر :
https://twitter.com/osamaahmadgalal
البريد الإلكتروني للتواصل :
OsamaAhmadGalal@Hotmail.Com
OsamaAhmadGalal@Yahoo.Com
OsamaAhmadGalal@Gmail.Com
رقم الموبايل :
00201122777845

الرد }}}
تم الشكر بواسطة: الاصيله
#2
السلام عليكم

ولكن عندي سؤال

هل بالامكان ان يكون الخادم يستخدم لغة اخرى غير الجافا وربطه بعميل جافا
(( يَا أَيَّتُهَا النَّفْسُ الْمُطْمَئِنَّةُ ارْجِعِي إِلَى رَبِّكِ رَاضِيَةً مَرْضِيَّةً فَادْخُلِي فِي عِبَادِي وَادْخُلِي جَنَّتِي ))

الرد }}}
تم الشكر بواسطة:
#3
أخي الموضوع منقول من الأخ Friendassist زي ما انتا شايف وأنا معنديش فكرة عن الجافا اصلا بس لو كنت عارف الإجابة كنت هقول لك والله
رابط قناتي على اليوتيوب :
https://www.youtube.com/user/OsamaAhmadGalal
رابط حساب الفيسبوك :

https://www.facebook.com/P.Osama.Ahmad.Galal
رابط حساب التويتر :
https://twitter.com/osamaahmadgalal
البريد الإلكتروني للتواصل :
OsamaAhmadGalal@Hotmail.Com
OsamaAhmadGalal@Yahoo.Com
OsamaAhmadGalal@Gmail.Com
رقم الموبايل :
00201122777845

الرد }}}
تم الشكر بواسطة:
#4
شكرا .
(( نحن قوم أعزنا الله بالإسلام فمهما ابتغينا العزة بغيره أذلنا الله )) .. 











الرد }}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  هيا بنا نبدأ مع لغة الجافا ... Java أسامة أحمد 3 5,806 26-03-17, 07:37 AM
آخر رد: الخير طهوري
  الاتصال عن بعد من خلال الجافا .. Remote Control RaggiTech 1 4,651 07-10-12, 11:41 AM
آخر رد: RaggiTech
  مكتبات الجافا مفتوحة المصدر !! أسامة أحمد 0 3,637 15-09-12, 03:02 PM
آخر رد: أسامة أحمد

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم