多線程+socket實現多人聊天室


最近在學習多線程的時候打算做一個簡單的多線程socke聊天的程序,結果發現網上的代碼都沒有完整的實現功能,所以自己實現了一個demo:

demo功能大致就是,有一個服務端負責信息轉發,多個客戶端發送消息,當一個客戶端發送消息時,其他的客戶端都可以接受到。

服務端:

客戶端:

 

客戶端代碼:

package com.cky.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {
    private PrintWriter out;
    //private BufferedReader br;
    private Scanner scan;
    private Boolean flag=true;
    private Socket s;
    private InputStream is;
    
    public Client() throws UnknownHostException, IOException {
        s=new Socket("127.0.0.1", 5001);
        is=s.getInputStream();
    }
    
    public static void main(String []args) throws UnknownHostException, IOException {
        Client client =new Client();
        client.startup();
    }
    public void startup() throws UnknownHostException, IOException {
        out = new PrintWriter(s.getOutputStream(), true);  
        
        //開啟一個線程監聽服務端的消息
        Thread ct=new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    if(!flag) break;
                    try {
                        receive();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        });
        ct.start();
        //主線程負責發送消息
        System.out.println("請輸入你的用戶名:");
        scan = new Scanner(System.in);
        String name=scan.nextLine();
        out.println(name);
        System.out.println(name+",歡迎進入聊天室,輸入quit退出");
        while(flag) {
            String read=scan.nextLine();
            if(read.equalsIgnoreCase("quit")) {
                flag=false;
            }
            //System.out.println(read);
            out.println(read);
        }
        s.close();
    }
    
    public void receive() throws IOException {
        byte ss[]=new byte[1024];
        int length=s.getInputStream().read(ss);
        System.out.println(new String(ss,0,length));
    }
}

服務端代碼:

package com.cky.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server {
    private List<ThreadServer> clients=new ArrayList<ThreadServer>();
    public void startup() throws IOException {
        System.out.println("監聽5001端口");
        ServerSocket ss=new ServerSocket(5001);
        while(true){
            Socket socket=ss.accept();
            System.out.println("發現新用戶");
            Thread st=new Thread(new ThreadServer(socket));
            st.start();
        }
    }
    
    public class ThreadServer implements Runnable{
        private Socket socket;
        private BufferedReader br;
        private PrintWriter out;
        private String name;
        private Boolean flag=true;
        public ThreadServer(Socket socket) throws IOException {
            this.socket=socket;
            br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out=new PrintWriter(socket.getOutputStream(),true);
            String str=br.readLine();
            name=str+"["+socket.getInetAddress().getHostAddress()+":"+socket.getPort()+"]";
            System.out.println(name+"加入該聊天室");
            send(name+"加入該聊天室");
            clients.add(this);
        }
        private void send(String message) {
            for (ThreadServer threadServer : clients) {
                System.out.println("-->已向線程"+threadServer.name+"發送消息");
                threadServer.out.print(message);
                threadServer.out.flush();
            }
        }
        private void receive() throws IOException {
            String message;
            while(flag=true) {
                message=br.readLine();
                if(message.equalsIgnoreCase("quit")) {
                    System.out.println("用戶"+name+"退出了");
                    out.println("quit");
                    out.flush();
                    clients.remove(this);
                    flag=false;
                }
                System.out.println(name+":"+message);
                send(name+":"+message);
            }
        }
        @Override
        public void run() {
            try {
                while(flag=true) {
                    receive();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    public static void main(String []args) throws IOException {
        Server server=new Server();
        System.out.println("服務器開啟");
        server.startup();
    }
    
}

先啟動服務端,監聽端口,再使用客戶端登錄發送消息。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM