1. 程式人生 > >JAVA_網路程式設計_TCP_Socket通訊_聊天室_多人聊天/私聊_實現

JAVA_網路程式設計_TCP_Socket通訊_聊天室_多人聊天/私聊_實現

Socket程式設計 連線(連線是通過輸入輸出流來傳送資料)

 

建立伺服器

package com.hp.tcp;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * 服務端
 *
 * @author 曉電腦
 */
public class Service {

    //建立一個容器用於接受每一個連線
    private List<ServiceThread> serviceThreadList=new ArrayList<>();

    public static void main(String[] args) throws IOException {
        new Service().connect();
    }

    public void connect() throws IOException {
        //建立伺服器 指定埠
        ServerSocket socket = new ServerSocket(8888);
        while (true) {
            Socket accept = socket.accept();
            ServiceThread thread = new ServiceThread(accept);
            serviceThreadList.add(thread);
            new Thread(thread).start();
        }
    }


    class ServiceThread implements Runnable {


        private DataInputStream stream;

        private DataOutputStream outputStream;

        private boolean isRuning = true;

        private String name;


        public ServiceThread() {

        }

        public ServiceThread(Socket socket) {
            try {
                //接受客戶端的資料的流
                stream = new DataInputStream(socket.getInputStream());
                //返回客戶端資料的流
                outputStream = new DataOutputStream(socket.getOutputStream());
                 this.name = stream.readUTF();
                send("歡迎進入聊天室");
                sendOthers(name+"進入了聊天室",false);
            } catch (IOException e) {
                // e.printStackTrace();
                CloseUtils.close(stream, outputStream);
                isRuning = false;
                serviceThreadList.remove(this);
            }

        }

        /**
         * 接受客戶端資料
         *
         * @return
         */
        public String accept() {
            String readUTF = null;
            try {
                readUTF = stream.readUTF();
            } catch (IOException e) {
                // e.printStackTrace();
                CloseUtils.close(stream);
                isRuning = false;
                serviceThreadList.remove(this);
            }
            return readUTF;
        }

        /**
         * 傳送客戶端資料
         */
        public void send(String acept) {
            try {
                    outputStream.writeUTF(acept);
                    outputStream.flush();

            } catch (IOException e) {
                // e.printStackTrace();
                CloseUtils.close(stream);
                isRuning = false;
                serviceThreadList.remove(this);
            }
        }

        /**
         * 發給其他客戶端
         */
        public void  sendOthers(String accept,boolean flag){
            //私聊的實現
            if (accept.startsWith("@") && accept.indexOf(":")>-1){
                String title=accept.substring(1,accept.indexOf(":"));
                String content=accept.substring(accept.indexOf(":")+1);
                for (ServiceThread serviceThread : serviceThreadList) {
                    if (serviceThread.name.equals(title)){
                            serviceThread.send(this.name+"對你私聊說"+content);
                    }
                }

            }else {
                for (ServiceThread serviceThread : serviceThreadList) {
                    if (serviceThread.equals(this))continue;
                    if (flag){
                        serviceThread.send(this.name+"對所有人說"+accept);
                    }else {
                        serviceThread.send("系統訊息"+accept);
                    }

                }
            }

        }

        @Override
        public void run() {
            while (isRuning){
                sendOthers(accept(),true);
            }
        }
    }
}

 

建立客戶端

 

package com.hp.tcp;

import java.io.*;
import java.net.Socket;


/**客戶端
 * @author 曉電腦
 */
public class Client {
    public static void main (String[] args) throws IOException {
        System.out.println("請輸入名稱");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String readLine = reader.readLine();
        if (readLine == null){
            return;
        }

        //建立客戶端 指定伺服器
        Socket socket = new Socket("localhost",8888);
        new Thread(new Send(socket,readLine)).start();
        new Thread(new Accept(socket)).start();
    }
}

 

建立傳送資訊的執行緒

package com.hp.tcp;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**傳送訊息執行緒
 * @author 曉電腦
 */
public class Send implements Runnable {

    private BufferedReader bufferedReader;

    private DataOutputStream dataOutputStream;

    private boolean isRun=true;

    //名稱
    private String name;

    public Send(){
        bufferedReader=new BufferedReader(new InputStreamReader(System.in));
    }

    public Send(Socket socket,String name){
        this();
        try {
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            this.name=name;
            send(name);
        } catch (IOException e) {
            //e.printStackTrace();
            isRun=false;
            CloseUtils.close(dataOutputStream,bufferedReader);
        }
    }

    /**
     * 接受伺服器資料
     * @return
     */
    public String accept(){
        String readLine=null;
        try {
            readLine = bufferedReader.readLine();
        } catch (IOException e) {
            //e.printStackTrace();
            isRun=false;
            CloseUtils.close(dataOutputStream,bufferedReader);
        }
        return readLine;
    }


    /**
     * 發給伺服器資料
     * @param str
     */
    public void send(String str){
        try {
            dataOutputStream.writeUTF(str);
        } catch (IOException e) {
          //  e.printStackTrace();
            isRun=false;
            CloseUtils.close(dataOutputStream,bufferedReader);
        }

    }

    @Override
    public void run() {
        while (isRun){
            send(accept());
        }
    }
}

 

接受訊息執行緒

 

package com.hp.tcp;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

/**
 * 接受的執行緒
 */
public class Accept implements Runnable {
    private DataInputStream dataInputStream;
    private boolean isRun=true;
    public Accept(){}
    public Accept(Socket socket){
        try {
            this.dataInputStream=new DataInputStream(socket.getInputStream());
        } catch (IOException e) {
           // e.printStackTrace();
            CloseUtils.close(dataInputStream);
            isRun=false;
        }
    }


    public void write(){
        String str=null;
        try {
             str=dataInputStream.readUTF();
            System.out.println(str);
        } catch (IOException e) {
           // e.printStackTrace();
            CloseUtils.close(dataInputStream);
            isRun=false;
        }
    }
    @Override
    public void run() {
        while (isRun){
            write();
        }
    }
}

 

群聊執行效果為

在另一個客戶端可以接受到

 

私聊功能的效果

 

在qwe客戶端可以接受到

 

 

在另一個客戶端是接收不到私聊資料的