聊天室Socker实现

 

1.创建一个服务端

 

// 创建serverSocket
ServerSocket serverSocket = new ServerSocket(9999);
// 获取一个客户端socket
Socket client = serverSocket.accept();
// 给客户端发送数据
PrintWriter writer = new PrintWriter(client.getOutputStream(),true);
writer.println("连接成功");
while(true) {
// 接收客户端发送的数据
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line = reader.readLine();
//System.out.println(line);
​
//Scanner scanner = new Scanner(System.in);
//String line1 = scanner.nextLine();
// 发送数据
writer.println("服务端返回的数据:"+line);
        }

 

2.创建一个客户端

 

// 客户端socket
Socket socket = new Socket("localhost",9999);
String line;
do {
// 接收服务端发送数据
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 读取数据
String line1 = reader.readLine();
System.out.println(line1);
// 发送给服务器
PrintWriter writer = new PrintWriter(socket.getOutputStream(),true);
// 从控制台录入数据
Scanner scanner = new Scanner(System.in);
// 读取一行数据
line = scanner.nextLine();
// 输入给服务器
writer.println(line);
} while(!"quit".equalsIgnoreCase(line));

 

3.这就是一个简单的客户端发送消息给服务端

 

4.多人的一个聊天室:Server 类

 

  /**
     * 启动服务端的方法
     */
    public void start(int port) {
        ServerSocket serverSocket = null;
        try {
            // 创建服务端
            serverSocket = new ServerSocket(port);
            // 循环获取客户端
            while(true){
                // 获取客户端
                Socket client = serverSocket.accept();
​
                // 创建一个服务端线程,用于处理每一个客户端的请求
                ServerThread thread = new ServerThread(client);
                // 开启线程
                thread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (serverSocket != null) {
                try {
                    // 关闭服务端
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 

5.客户端类: Client 类

 

public class Client {
​
    // 判断是否可以读取
    private boolean flag = true;
    private Socket client = null;
​
    public void start(String host, int port) {
        //Socket client = null;
        ClientThread thread = null;
        try {
            // 创建客户端
            client = new Socket(host, port);
            // 创建一个线程,用于接收服务端发送的消息
            thread = new ClientThread();
            thread.start();
            // 向服务器发送数据
            String msg = "";
            do {
                // 接收控制台录入数据
                Scanner scanner = new Scanner(System.in);
                // 读取一行
                msg = scanner.nextLine();
                // 发送到服务器
                PrintWriter writer = new PrintWriter(client.getOutputStream(), true);
                writer.println(msg);
                if ("quit".equals(msg)) {
                    flag = false;
                    client.close();
                }
            } while (flag);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (client != null) {
                try {
                    // 终端线程
                    thread.interrupt();
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
​
    private class ClientThread extends Thread {
        //private Socket client;
        private BufferedReader reader;
​
        ClientThread() {
            try {
                //this.client = client;
                this.reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            } catch (IOException e) {
                e.printStackTrace();
            }
​
        }
​
        @Override
        public void run() {
            // 获取消息,并打印到控制台
            String msg = null;
            do {
                if (flag) {
                    // 接收消息
                    msg = read();
                    System.out.println(msg);
                }
            } while (msg != null && !"退出成功".equals(msg));
        }
​
        private String read() {
            String msg = null;
            try {
                if (!client.isClosed()) {
                    msg = reader.readLine();
                }
            } catch (IOException e) {
                //e.printStackTrace();
                msg = "退出成功";
            } finally {
                if (msg == null) {
                    msg = "退出成功";
                }
            }
            return msg;
        }
    }
}
​

 

6.线程类ServerThread

 

public class ServerThread extends Thread {
    /**
     * 存储聊天是中的客户端
     */
    private static final Map<String, Socket> CLIENT_SOCKETS = new HashMap<>();
​
    private Socket client;
    private String ip;
    private BufferedReader in;
​
    ServerThread(Socket client) {
        try {
            this.client = client;
            // 获取客户端的IP
            this.ip = client.getInetAddress().getHostAddress();
            this.in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 通知其他人上线了
        send("上线了");
        // 把客户端存到列表中
        CLIENT_SOCKETS.put(ip, client);
    }
​
    @Override
    public void run() {
        // 读取客户端发送的消息,并把消息转发到所有的客户端中
        String msg = "";
        do {
            // 接收消息
            msg = read();
            // 发消息
            send(msg);
        } while (msg != null && !"quit".equals(msg));
    }
​
    public void close() {
        if (!client.isClosed()) {
            // 1.告诉自己退出成功
            sendOne(client, "退出成功");
        }
        // 在在线列表中移除
        CLIENT_SOCKETS.remove(this.ip);
        // 2.告诉其他人下线了
        sendAll("[" + this.ip + "]: 下线了");
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (client != null) {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
​
    /**
     * 读取客户端发送的消息
     *
     * @return
     */
    public String read() {
        String msg = "";
        try {
            // 判断当前的socket是否被关闭了
            if (!client.isClosed()) {
                msg = in.readLine();
            }
        } catch (IOException e) {
            //e.printStackTrace();
            close();
        }
        return msg;
    }
​
    public void send(String msg) {
                Iterator<Socket> iterator = CLIENT_SOCKETS.values().iterator();
            while (iterator.hasNext()) {
                Socket socket = iterator.next();
                try {
                    PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
                    // 如果 客户端发送的消息是"quit",则告知其他人它以退出
                    if ("quit".equals(msg)) {
                        if (socket == this.client) {
                            writer.println("退出成功");
                            // 在在线列表中移除
                            CLIENT_SOCKETS.remove(this.ip);
                        } else {
                            writer.println("[" + this.ip + "]: 下线了");
                        }
                    } else {
                     writer.println("[" + this.ip + "]: " + msg);
                    } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }                 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值