• java bio 之聊天室


    最近在复习java io相关知识 ,发现很多细节之前没学习到位,原理也没吃透,只能感叹本人愚钝。

    复习到bio,顺手写了个简单的聊天室功能,并和大家分享下。

    服务端:

    package io.QQ聊天室实现_BIO;
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;
    
    public class ChartServer {
        public static void main (String[] args) throws IOException {
            ChartServer server = new ChartServer();
            server.init(8889).listener();
        }
        private ServerSocket serverSocket;
        private final List<ProcessorThread> clients = new ArrayList<>();
        public ChartServer init(int port) throws IOException {
            this.serverSocket =new ServerSocket(port);
            return this;
        }
        public void listener() throws IOException {
            //主线程负责监听,启动监听线程
            System.out.println("listener start");
            new Thread(new AcceptThread(serverSocket)).start();
        }
    
        class AcceptThread implements Runnable{
            private ServerSocket serverSocket;
    
            public AcceptThread (ServerSocket serverSocket) {
                this.serverSocket = serverSocket;
            }
    
            @Override
            public void run () {
                while (true){
                    try {
                        Socket socket = serverSocket.accept();
                        //子线程负责分发任务
                        new Thread(new ProcessorThread(socket)).start();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        class ProcessorThread implements Runnable{
            Socket socket;
    
            public ProcessorThread (Socket socket) {
                this.socket = socket;
            }
    
            @Override
            public void run () {
                String key = "["+socket.getInetAddress().getHostAddress()+":"+socket.getPort()+"]";
                System.out.println(key+"上线了");
                try {
                    writeMsg(socket,key+"上线了");
                    clients.add(this);
                    readMsg(socket,key);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            public String readMsg(Socket socket,String name) throws IOException {
    
                BufferedReader br =  new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String readLine;
                while (true){
                    readLine = br.readLine();
                    System.out.println(name+"说:"+readLine);
                    writeMsg(socket,name+"说:"+readLine);
                }
            }
    
            public void writeMsg(Socket socket,String msg) throws IOException {
                //轮询
                OutputStream os;
                for(ProcessorThread s:clients){
                    os = s.socket.getOutputStream();
                    os.write(msg.getBytes());
                    os.write("
    ".getBytes());
                    os.flush();
                }
            }
        }
    }

    客户端:

    package io.QQ聊天室实现_BIO;
    
    import java.io.*;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class ChartClient {
    
        private  Socket socket;
    
        public void init(String host,int port) throws IOException {
    
            Scanner scanner = new Scanner(System.in);
            socket = new Socket(host,port);
            new Thread(new readThread(socket)).start();
            while (scanner.hasNextLine()){
                String inputStr = scanner.nextLine();
                OutputStream os = socket.getOutputStream();
    
                OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
                osw.write(inputStr);
                osw.write("
    ");
                osw.flush();
            }
        }
    
         class readThread implements Runnable{
    
            Socket socket;
    
             InputStream answer ;
             public readThread (Socket socket) throws IOException {
                 this.socket = socket;
                 answer = socket.getInputStream();
             }
    
             @Override
             public void run () {
                 while (true){
                     BufferedReader br = new BufferedReader(new InputStreamReader(answer));
                     try {
                         StringBuffer sb = new StringBuffer();
                         String readLine;
                         while (true){
                             readLine = br.readLine();
                             sb.append(readLine);
                             System.out.println(readLine);
                         }
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
                 }
             }
         }
    
    
        static String host = "127.0.0.1";
        static int port = 8889;
        public static void main (String[] args) throws IOException {
            ChartClient chartClient = new ChartClient();
            chartClient.init(host,port);
        }
    
    }

    总结:

      在本例中,最重要的是要理解socket.accept()方法是阻塞的。bio中提供的流写入读取是阻塞的,如inputStream.read 是阻塞的。BufferedReader.readline()的结束标志。

    在java网络编程或者java多线程编程中,线程分工是很重要的思想,可以参照tomcat等成熟容器的设计学习。

  • 相关阅读:
    shiro之cache问题
    SpringMVC关于请求参数乱码问题
    js递归错误
    说说Javac
    说说CDN
    谈谈HTTP
    谈谈Ajax(二)
    谈谈Ajax(一)
    记一次关于SSM框架的使用错误
    MP实战系列(十四)之分页使用
  • 原文地址:https://www.cnblogs.com/luoluoshidafu/p/8823287.html
Copyright © 2020-2023  润新知