Rhyme/ java TCP网络编程 聊天室(群聊与私聊)TCP、多线程、IO流编程完整代码实现

TCP网络编程 聊天室(群聊与私聊)完整代码实现

实现工具:Socket、多线程、IO流

实现效果图

这里写图片描述

这里写图片描述

Client.java

package com.maple.tcp;

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

/**
 * Client based on tcp protocol
 * 
 * @author RhymeChiang
 * @date 2017/10/22
 */
public class Client {
    public static void main(String[] args) {
        try {

            System.out.println("    Please input your name!");
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String name = br.readLine();

            Socket client = new Socket("localhost", 8888);
            new Thread(new Send(client, name)).start();
            new Thread(new Receive(client)).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Server.java

package com.maple.tcp;

import static org.hamcrest.CoreMatchers.instanceOf;

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;

/**
 * tcp server
 * 
 * @author RhymeChiang
 * @date 2017/10/22
 */
public class Server {
    /**
     * server
     */
    private ServerSocket server = null;

    /**
     * list of client
     */
    private List<AClient> list = null;

    public Server() throws IOException {
        server = new ServerSocket(8888);
        list = new ArrayList<>();
    }

    public void start() {
        while (true) {
            AClient client = new AClient();
            list.add(client);
            new Thread(client).start();
        }
    }

    /**
     * each Client has a dependant Thread
     * 
     * @author RhymeChiang
     * @date 2017/10/22
     */
    private class AClient implements Runnable {

        private DataInputStream dis = null;
        private DataOutputStream dos = null;
        private Socket client = null;
        private boolean isRunning = true;
        private String clientName = null;

        public AClient() {
            try {
                client = server.accept();
                dis = new DataInputStream(client.getInputStream());
                dos = new DataOutputStream(client.getOutputStream());
                clientName = dis.readUTF();
                send("  Welcome!" + clientName);
                officialSendOthers("    Hi,everyone!" + clientName + " joined us");
            } catch (IOException e) {
                isRunning = false;
                IOUtil.closeAll(dos, dis);
                list.remove(this);
            }
        }

        /**
         * receive message from client
         * 
         * @return
         * @throws IOException
         */
        public String receive() {
            try {
                return dis.readUTF();
            } catch (IOException e) {
                isRunning = false;
                IOUtil.closeAll(dos, dis);
                list.remove(this);
            }
            return "";
        }

        public void send(String msg) {
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                isRunning = false;
                IOUtil.closeAll(dos, dis);
                list.remove(this);
            }
        }

        /**
         * send message to others
         * 
         * @param msg
         */
        public void sendOthers(String msg) {
            if(list.size()==0) {
                send("  "+"sorry,there is nobody in this chat room now");
                return;
            }
            for (AClient a : list) {
                if (a == this) {
                    continue;
                }
                a.send("    "+clientName + " said to everyone:" + msg);
            }
        }

        public void officialSendOthers(String msg) {
            for (AClient a : list) {
                a.send(msg);
            }
        }

        public String getClientName() {
            return clientName;
        }

        /**
         * if the msg is a private conversation
         * 
         * @param msg
         * @return
         */
        public boolean privateSession(String msg) {
            String reg = "@[a-zA-Z0-9_-]{3,16}:";
            String msgHead = msg.substring(0,msg.indexOf(":")+1);
            if (msgHead.matches(reg)) {
                // target private conversation
                String name = msg.substring(msg.indexOf("@") + 1, msg.indexOf(":"));
                // the content of private conversation
                String sendMsg = msg.substring(msg.indexOf(":") + 1);
                for (AClient a : list) {
                    if (a.getClientName().equals(name)) {
                        // send conversation
                        a.send("    "+this.getClientName() + " said to you: " + sendMsg);
                        return true;
                    }
                }
                send("  "+name + " is not online");
                return false;
            }
            return false;
        }

        @Override
        public void run() {
            while (isRunning) {
                String msg = receive();
                System.out.println(msg);
                // private conversation
                if (!privateSession(msg)) {
                    sendOthers(msg);
                }
            }
        }

    }

    public static void main(String[] args) {

        try {
            new Server().start();
        } catch (IOException e) {
            e.printStackTrace();
        }

        /*
         * String msg = "@Rhyme:nihao";
         * System.out.println(msg.substring(msg.indexOf("@") + 1, msg.indexOf(":")));
         */
    }
}

Send.java

package com.maple.tcp;

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

/**
 * thread of send
 * 
 * @author RhymeChiang
 * @date 2017/10/22
 */
public class Send implements Runnable {
    /**
     * outputStream
     */
    private DataOutputStream dos = null;
    /**
     * console inputStream
     */
    private BufferedReader console = null;
    /**
     * the mark of is thread running well
     */
    private boolean isRunning = true;

    /**
     * the name of current client
     */
    private String clientName;

    public Send(Socket client,String name) {
        super();
        try {
            this.clientName = name;
            dos = new DataOutputStream(client.getOutputStream());
            console = new BufferedReader(new InputStreamReader(System.in));
            //send clintName to server
            dos.writeUTF(clientName);
        } catch (IOException e) {
            // when it comes to exception close current thread
            isRunning = false;
            // close input/output streams
            IOUtil.closeAll(dos);
        }
    }

    /**
     * get message from console
     * 
     * @return the message is going to be send
     * @throws IOException
     */
    public String getMsgFormConsole() {
        try {
            return console.readLine();
        } catch (IOException e) {
            //e.printStackTrace();
            IOUtil.closeAll(console);
        }
        return "";
    }

    /**
     * send message
     * 
     * @param msg
     *            message going to be send
     */
    private void send(String msg) {
        try {
            //make sure the msg is not null and not "" 
            if(null!=msg&&!msg.equals("")) {
                dos.writeUTF(msg);
                dos.flush();
            }
        } catch (IOException e) {
            isRunning = false;
            IOUtil.closeAll(dos);
        }
    }

    @Override
    public void run() {
        while (isRunning) {
            //send message from console
            send(getMsgFormConsole());
        }
    }

}

Receive.java

package com.maple.tcp;

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

/**
 * Receiver of tcp client
 * 
 * @author RhymeChiang
 * @date 2017/10/22
 */
public class Receive implements Runnable {

    /**
     * input stream from the server
     */
    private DataInputStream dis = null;

    /**
     * input stream from the server
     */
    private boolean isRunning = true;

    public Receive(Socket client) {
        super();
        try {
            dis = new DataInputStream(client.getInputStream());
        } catch (IOException e) {
            isRunning = false;
            IOUtil.closeAll(dis);
        }
    }

    /**
     * receive message from server
     */
    public void receive() {
        try {
            String str = dis.readUTF();
            System.out.println(str);
        } catch (IOException e) {
            isRunning = false;
            IOUtil.closeAll(dis);
        }
    }

    @Override
    public void run() {
        while (isRunning) {
            receive();
        }
    }

}

IOUtil.java

package com.maple.tcp;

import java.io.Closeable;
import java.io.IOException;

/**
 * util of io close
 * @author RhymeChiang
 * @date 2017/10/22
 */
public class IOUtil {

    public static void closeAll(Closeable...io) {
        for(Closeable i : io) {
            if(null!=i) {
                try {
                    i.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值