zoukankan      html  css  js  c++  java
  • 01基于BIO的多人聊天室

    聊天室服务端实现

    聊天主干逻辑

     1 package server;
     2 
     3 import java.io.BufferedWriter;
     4 import java.io.IOException;
     5 import java.io.OutputStreamWriter;
     6 import java.io.Writer;
     7 import java.net.ServerSocket;
     8 import java.net.Socket;
     9 import java.util.HashMap;
    10 import java.util.Map;
    11 
    12 public class ChatServer {
    13 
    14     private int DEFAULT_PORT = 8888;
    15     private final String QUIT = "quit";
    16 
    17     private ServerSocket serverSocket;
    18     private Map<Integer, Writer> connectedClients;
    19 
    20     public ChatServer() {
    21         connectedClients = new HashMap<>();
    22     }
    23 
    24     public synchronized void addClient(Socket socket) throws IOException {
    25         if (socket != null) {
    26             int port = socket.getPort();
    27             BufferedWriter writer = new BufferedWriter(
    28                     new OutputStreamWriter(socket.getOutputStream())
    29             );
    30             connectedClients.put(port, writer);
    31             System.out.println("客户端[" + port + "]已连接到服务器");
    32         }
    33     }
    34 
    35     public synchronized void removeClient(Socket socket) throws IOException {
    36         if (socket != null) {
    37             int port = socket.getPort();
    38             if (connectedClients.containsKey(port)) {
    39                 connectedClients.get(port).close();
    40             }
    41             connectedClients.remove(port);
    42             System.out.println("客户端[" + port + "]已断开连接");
    43         }
    44     }
    45 
    46     public synchronized void forwardMessage(Socket socket, String fwdMsg) throws IOException {
    47         for (Integer id : connectedClients.keySet()) {
    48             if (!id.equals(socket.getPort())) {
    49                 Writer writer = connectedClients.get(id);
    50                 writer.write(fwdMsg);
    51                 writer.flush();
    52             }
    53         }
    54     }
    55 
    56     public boolean readyToQuit(String msg) {
    57         return QUIT.equals(msg);
    58     }
    59 
    60     public synchronized void close() {
    61         if (serverSocket != null) {
    62             try {
    63                 serverSocket.close();
    64                 System.out.println("关闭serverSocket");
    65             } catch (IOException e) {
    66                 e.printStackTrace();
    67             }
    68         }
    69     }
    70 
    71     public void start() {
    72 
    73         try {
    74             // 绑定监听端口
    75             serverSocket = new ServerSocket(DEFAULT_PORT);
    76             System.out.println("启动服务器,监听端口:" + DEFAULT_PORT + "...");
    77 
    78             while (true) {
    79                 // 等待客户端连接
    80                 Socket socket = serverSocket.accept();
    81                 // 创建ChatHandler线程
    82                 new Thread(new ChatHandler(this, socket)).start();
    83             }
    84 
    85         } catch (IOException e) {
    86             e.printStackTrace();
    87         } finally {
    88             close();
    89         }
    90     }
    91 
    92     public static void main(String[] args) {
    93         ChatServer server = new ChatServer();
    94         server.start();
    95     }
    96 
    97 }

    聊天任务

     1 package server;
     2 
     3 import java.io.*;
     4 import java.net.Socket;
     5 
     6 public class ChatHandler implements Runnable {
     7 
     8     private ChatServer server;
     9     private Socket socket;
    10 
    11     public ChatHandler(ChatServer server, Socket socket) {
    12         this.server = server;
    13         this.socket = socket;
    14     }
    15 
    16     @Override
    17     public void run() {
    18         try {
    19             // 存储新上线用户
    20             server.addClient(socket);
    21 
    22             // 读取用户发送的消息
    23             BufferedReader reader = new BufferedReader(
    24                     new InputStreamReader(socket.getInputStream())
    25             );
    26 
    27             String msg = null;
    28             while ((msg = reader.readLine()) != null) {
    29                 String fwdMsg = "客户端[" + socket.getPort() + "]: " + msg + "
    ";
    30                 System.out.print(fwdMsg);
    31 
    32                 // 将消息转发给聊天室里在线的其他用户
    33                 server.forwardMessage(socket, fwdMsg);
    34 
    35                 // 检查用户是否准备退出
    36                 if (server.readyToQuit(msg)) {
    37                     break;
    38                 }
    39             }
    40         } catch (IOException e) {
    41             e.printStackTrace();
    42         } finally {
    43             try {
    44                 server.removeClient(socket);
    45             } catch (IOException e) {
    46                 e.printStackTrace();
    47             }
    48         }
    49     }
    50 }

    聊天室客户端

    监听服务端推送的消息

     1 package client;
     2 
     3 import java.io.*;
     4 import java.net.Socket;
     5 
     6 public class ChatClient {
     7 
     8     private final String DEFAULT_SERVER_HOST = "127.0.0.1";
     9     private final int DEFAULT_SERVER_PORT = 8888;
    10     private final String QUIT = "quit";
    11 
    12     private Socket socket;
    13     private BufferedReader reader;
    14     private BufferedWriter writer;
    15 
    16     // 发送消息给服务器
    17     public void send(String msg) throws IOException {
    18         if (!socket.isOutputShutdown()) {
    19             writer.write(msg + "
    ");
    20             writer.flush();
    21         }
    22     }
    23 
    24     // 从服务器接收消息
    25     public String receive() throws IOException {
    26         String msg = null;
    27         if (!socket.isInputShutdown()) {
    28             msg = reader.readLine();
    29         }
    30         return msg;
    31     }
    32 
    33     // 检查用户是否准备退出
    34     public boolean readyToQuit(String msg) {
    35         return QUIT.equals(msg);
    36     }
    37 
    38     public void close() {
    39         if (writer != null) {
    40             try {
    41                 System.out.println("关闭socket");
    42                 writer.close();
    43             } catch (IOException e) {
    44                 e.printStackTrace();
    45             }
    46         }
    47     }
    48 
    49     public void start() {
    50 
    51         try {
    52             // 创建socket
    53             socket = new Socket(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);
    54 
    55             // 创建IO流
    56             reader = new BufferedReader(
    57                     new InputStreamReader(socket.getInputStream())
    58             );
    59             writer = new BufferedWriter(
    60                     new OutputStreamWriter(socket.getOutputStream())
    61             );
    62 
    63             // 处理用户的输入
    64             new Thread(new UserInputHandler(this)).start();
    65 
    66             // 读取服务器转发的消息
    67             String msg = null;
    68             while ((msg = receive()) != null) {
    69                 System.out.println(msg);
    70             }
    71         } catch (IOException e) {
    72             e.printStackTrace();
    73         } finally {
    74             close();
    75         }
    76     }
    77 
    78     public static void main(String[] args) {
    79         ChatClient chatClient = new ChatClient();
    80         chatClient.start();
    81     }
    82 }

    处理用户输入

     1 package client;
     2 
     3 import client.ChatClient;
     4 import java.io.*;
     5 
     6 public class UserInputHandler implements Runnable {
     7 
     8     private ChatClient chatClient;
     9 
    10     public UserInputHandler(ChatClient chatClient) {
    11         this.chatClient = chatClient;
    12     }
    13 
    14     @Override
    15     public void run() {
    16         try {
    17             // 等待用户输入消息
    18             BufferedReader consoleReader =
    19                     new BufferedReader(new InputStreamReader(System.in));
    20             while (true) {
    21                 String input = consoleReader.readLine();
    22 
    23                 // 向服务器发送消息
    24                 chatClient.send(input);
    25 
    26                 // 检查用户是否准备退出
    27                 if (chatClient.readyToQuit(input)) {
    28                     break;
    29                 }
    30             }
    31         } catch (IOException e) {
    32             e.printStackTrace();
    33         }
    34     }
    35 }
  • 相关阅读:
    Scrum Meeting 6 -2014.11.12
    Scrum Meeting 5 -2014.11.11
    Bing词典vs有道词典比对测试报告——体验篇之成长性及用户控制权
    团队项目的用户需求及反馈
    Scrum Meeting 4 -2014.11.8
    Scrum Meeting 3 -2014.11.5
    bing词典vs有道词典对比测试报告——功能篇之细节与用户体验
    Bing词典vs有道词典比对测试报告——功能篇之辅助功能,差异化功能及软件的效能
    Bing词典vs有道词典比对测试报告
    hdu 5087 次长升序串的长度
  • 原文地址:https://www.cnblogs.com/lpzh/p/14955160.html
Copyright © 2011-2022 走看看