实时群聊小程序开发记录

高洛峰
Lepaskan: 2017-02-10 13:31:38
asal
2718 orang telah melayarinya

昨天回忆了一下以前做的一个实时的群聊小程序。用JAVA写得。开发步骤如下:

这是面向过程的开发。

第一步,建立服务器端。

第二步,建立客户端并连接服务端。

第三步,客户端发送消息服务器端能接收到。

第四步,实现多客户连接服务端,并能接收多客户端发来的消息。可以采用多线程和异步的方法解决服务端被占用的情况。

第五步,服务端转发客户端发送的信息到每一个客户端。

第六步,消除小Bug。

ChatServer.java

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.util.*;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class ChatServer
{
    boolean started = false;
    ServerSocket ss = null;
                           
    List<Client> clients = new ArrayList<Client>();
                           
                           
    public static void main(String[] args)
    {
        new ChatServer().start();  
    }
    public void start(){
        try
        {
            ss = new ServerSocket(8881);
        }
        catch (BindException e){
            System.out.println("端口已被占用!");
            System.out.println("请结束相关进程!");
            System.exit(0);
        }
        catch (Exception e) {
                                   
            e.printStackTrace();
        }
        try{
            started = true;
            while (started)
            {
                Socket s = ss.accept(); //阻塞性函数,不断接收客户端连接
                Client c = new Client(s);//不能再静态main()里面new一个动态的方法,故将启动过程包装成一个public函数
System.out.println("a client connected");
                new Thread(c).start();
                clients.add(c);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }finally{
            try
            {
                ss.close();
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
                               
    }
                           
    class Client implements Runnable{//区分客户端,用一个线程操作一个客户端,也可以采用异步的方法。这里用线程,比较占资源。等我写出异步的方法后再共享。
        private Socket s= null;
        private DataInputStream dis= null;
        private DataOutputStream dos=null;
        private boolean bConnected = false;
        public Client(Socket s){
            this.s= s;
            try
            {
                dis=new DataInputStream(s.getInputStream());
                dos=new DataOutputStream(s.getOutputStream());
                bConnected = true;
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
                                   
        }
                               
        public void send(String str){       //
            try
            {
                dos.writeUTF(str);
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                clients.remove(this);
                System.out.println("一个客户退出了!List已去除");
                //e.printStackTrace();
            }
        }
                               
        public void run()
        {
            try
            {
                while (bConnected)
                {
                    String str;
                    str = dis.readUTF();// 阻塞性函数,会一直占用线程资源
System.out.println(str);
                    for (int i = 0; i < clients.size(); i++)
                    {
                        Client c = clients.get(i);
                        c.send(str);
                    }
                }
            }
            catch (EOFException e){
                System.out.println("一个客户已退出!");
            }catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                if(dis!=null)
                    try
                    {
                        dis.close();
                        if (dos != null)
                            dos.close();
                        if (s != null)
                            s.close();
                    } catch (SocketException e)
                    {
                            clients.remove(this);
                            System.out.println("一个客户已退出!");
                    }
                    catch (IOException e)
                    {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                                       
            }
        }
    }
}
Salin selepas log masuk

ChatClient.java

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
                                       
public class ChatClient extends Frame
{
    Socket s = null;
    DataOutputStream dos = null;
    DataInputStream dis = null;
    private boolean bConnected=false;
    TextField tfTxt = new TextField();//输入框
    TextArea taContent = new TextArea();//显示聊天信息框
                                          
                                          
    public static void main(String[] args)
    {
        new ChatClient().lanunchFrame();
    }
                                          
    public void lanunchFrame(){
        setLocation(400,300);
        this.setSize(300, 300);
        add(tfTxt,BorderLayout.SOUTH);
        add(taContent,BorderLayout.NORTH);
        pack();//调整空隙
        this.addWindowListener(new WindowAdapter(){
            @Override
            public void windowClosing(WindowEvent e)
            {
                disconnect();
                System.exit(0);
            }
        });
        tfTxt.addActionListener(new TexFileListener());
        setVisible(true);
        connect();
                                              
        new Thread(new RecvThread()).start();
    }
                                          
    public void connect(){
        try
        {
            s= new Socket("127.0.0.1",8881);
            dos=new DataOutputStream(s.getOutputStream());
            dis=new DataInputStream(s.getInputStream());
System.out.println("connected!");
            bConnected =true;
                                                  
        } catch (UnknownHostException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
                                          
    public void disconnect()
    {
        try
        {
            dos.close();
            dis.close();
            s.close();
        } catch (Exception e1)
        {
            e1.printStackTrace();
        }
        /*try
        {
            bConnected = false;  //保证
            recvThread.join();
        }
        catch (InterruptedException e){
            e.printStackTrace();
        }
        finally{
            try
            {
                dos.close();
                dis.close();
                s.close();
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
*/
    }
                                          
    private class TexFileListener implements ActionListener{
        public void actionPerformed(ActionEvent e)
        {
            String str=tfTxt.getText().trim();
            //taContent.setText(str);
            tfTxt.setText("");
            try
            {
                dos.writeUTF(str);
                dos.flush();
                //dos.close();
            } catch (IOException e1)
            {
                e1.printStackTrace();
            }
                                                  
        }
    }
    private class RecvThread implements Runnable{
        public void run()
        {
            try
            {
                while (bConnected)
                {
                    String str = dis.readUTF();
                    //System.out.println(str);
                    taContent.setText(taContent.getText()+str+&#39;\n&#39;);
                }
            }
            catch (SocketException e){
                System.out.println("已退出!");
            }
            catch (EOFException e){
                System.out.println("已退出!");
            }
            catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
Salin selepas log masuk


更多实时群聊小程序开发记录 相关文章请关注PHP中文网!


sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan