EchoServer和EchoClient模型的改进1之多线程

Posted 大佛拈花-GoSaint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EchoServer和EchoClient模型的改进1之多线程相关的知识,希望对你有一定的参考价值。

  在之前的EchoServer模型个EchoClient模型中,客户端和服务端只是单纯的一一对应的关系,如果存在多个客户端和一个服务端,这就需要具体处理了。在这里我们明显想到的第一种方案是使用多线程处理。为每一个客户端设置一个工作线程,来处理连接,如下所示:

 

此时我们改进server代码:

package com.asiaInfo.caozg.ch_03;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class EchoServerThread {
    private int port = 8000;
    private ServerSocket serverSocket;

    public EchoServerThread() throws IOException {
        serverSocket = new ServerSocket(port);
        System.out.println("服务器启动");
    }

    public void service() {
        while (true) {
            Socket socket = null;
            try {
                socket = serverSocket.accept();  //等待客户连接
                // 为每一个客户端创建一个线程
                Thread workThread = new Thread(new Handles(socket));
                //启动线程
                workThread.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

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

    private class Handles implements Runnable {
        private Socket socket;

        public Handles(final Socket socket) {
            this.socket = socket;
        }

        public String echo(String msg) {
            return "echo:" + msg;
        }

        private PrintWriter getWriter(Socket socket) throws IOException {
            OutputStream socketOut = socket.getOutputStream();
            return new PrintWriter(socketOut, true);
        }

        private BufferedReader getReader(Socket socket) throws IOException {
            InputStream socketIn = socket.getInputStream();
            return new BufferedReader(new InputStreamReader(socketIn));
        }

        @Override public void run() {
            try {
                System.out.println("New connection accepted "
                        + socket.getInetAddress() + ":" + socket.getPort());
                BufferedReader br = getReader(socket);
                PrintWriter pw = getWriter(socket);
                String msg = null;
                while ((msg = br.readLine()) != null) {
                    System.out.println(msg);
                    pw.println(echo(msg));
                    if (msg.equals("bye")) //如果客户发送的消息为“bye”,就结束通信
                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }

}

之前的客户端代码不变:

package com.asiaInfo.caozg.ch_03;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * @Authgor: gosaint
 * @Description:
 * @Date Created in 21:31 2018/1/7
 * @Modified By:客户端代码
 */
public class EchoClientThread {
    private String host = "localhost";
    private int port = 8000;
    private Socket socket;

    public EchoClientThread() throws IOException {
        socket = new Socket(host, port);
    }

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

    private PrintWriter getWriter(Socket socket) throws IOException {
        OutputStream socketOut = socket.getOutputStream();
        return new PrintWriter(socketOut, true);
    }

    private BufferedReader getReader(Socket socket) throws IOException {
        InputStream socketIn = socket.getInputStream();
        return new BufferedReader(new InputStreamReader(socketIn));
    }


    public void talk() throws IOException {
        try {
            BufferedReader br = getReader(socket);
            PrintWriter pw = getWriter(socket);
            BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
            String msg = null;
            while ((msg = localReader.readLine()) != null) {

                pw.println(msg);
                System.out.println(br.readLine());

                if (msg.equals("bye"))
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

以上是关于EchoServer和EchoClient模型的改进1之多线程的主要内容,如果未能解决你的问题,请参考以下文章

《Netty》4.实现自己的EchoClient

将 Qt EchoClient 连接到 https://www.websocket.org/echo.html 时赢得 QAbstractSocket::UnsupportedSocketOperat

使用自定义线程池优化EchoServer

使用twised实现一个EchoServer

EchoServer.java (阻塞模式)

EchoServer.java (非阻塞模式)