One BIO Demo

作者 : 开心源码 本文共3664个字,预计阅读时间需要10分钟 发布时间: 2022-05-12 共130人阅读

本文将实现一个输入字符表达式,输出算术结果的BIO程序。通过该程序能进一步帮助了解什么是同步阻塞IO。

服务端

BIOServer,启动服务端,并循环监听用户端连接,每监听到一个请求,创立一个新线程解决数据。注意serverSocket.accept()方法,在未接收到连接时,会一直阻塞。

public class BIOServer {    //默认的端口号    private static int DEFAULT_PORT = 7777;    //单例的ServerSocket    private static ServerSocket serverSocket;    //根据传入参数设置监听端口,假如没有参数调用以下方法并使用默认值    public static void start() throws IOException {        //使用默认值        start(DEFAULT_PORT);    }    public synchronized static void start(int port) throws IOException {        if (serverSocket != null) return;        try {            //通过构造函数创立ServerSocket            //假如端口合法且空闲,服务端就监听成功            serverSocket = new ServerSocket(port);           System.out.println("服务端已启动,端口号:" + port);            //通过无线循环监听用户端连接            //假如没有用户端接入,将阻塞在accept操作上。            while (true) {                Socket socket = serverSocket.accept();                new Thread(new ServerHandler(socket)).start();            }        } finally {            //少量必要的清除工作            if (serverSocket != null) {               System.out.println("服务端已关闭。");                serverSocket.close();                serverSocket = null;            }        }    }}

ServerHandler,线程解决数据流程。从输入流读数据,写数据到输出流。

public class ServerHandler implements Runnable {    private Socket socket;    public ServerHandler(Socket socket) {        this.socket = socket;    }    @Override    public void run() {        BufferedReader in = null;        PrintWriter out = null;        try {            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));            out = new PrintWriter(socket.getOutputStream(), true);            String expression;            int result;            while (true) {                //通过BufferedReader读取一行                //假如已经读到输入流尾部,返回null,退出循环                //假如得到非空值,就尝试计算结果并返回                if ((expression = in.readLine()) == null) break;                System.out.println(("服务端收到信息:" + expression));                result = Calculator.cal(expression);                out.println(result);            }        } catch (Exception e) {            e.printStackTrace();            System.out.println((e.getLocalizedMessage()));        } finally {            //少量必要的清除工作            if (in != null) {                try {                    in.close();                } catch (IOException e) {                    e.printStackTrace();                }                in = null;            }            if (out != null) {                out.close();                out = null;            }            if (socket != null) {                try {                    socket.close();                } catch (IOException e) {                    e.printStackTrace();                }                socket = null;            }        }    }}

Calculator,计算字符串的算术结果。注意0的ASCII码是48。

public class Calculator {    public static int cal(String expression) throws Exception {        char op = expression.charAt(1);        switch (op) {            case '+':                return (expression.charAt(0) - 48) + (expression.charAt(2) - 48);            case '-':                return (expression.charAt(0) - 48) - (expression.charAt(2) - 48);            case '*':                return (expression.charAt(0) - 48) * (expression.charAt(2) - 48);            case '/':                return (expression.charAt(0) - 48) / (expression.charAt(2) - 48);        }        throw new Exception("Calculator error");    }}

用户端

Client,和服务器建立TCP连接,并发送和接收数据。

public class Client {    //默认的端口号    private static int DEFAULT_SERVER_PORT = 7777;    private static String DEFAULT_SERVER_IP = "127.0.0.1";    public static void send(String expression) {        send(DEFAULT_SERVER_PORT, expression);    }    public static void send(int port, String expression) {        System.out.println(("算术表达式为:" + expression));        Socket socket = null;        BufferedReader in = null;        PrintWriter out = null;        try {            socket = new Socket(DEFAULT_SERVER_IP, port);            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));            out = new PrintWriter(socket.getOutputStream(), true);            out.println(expression);            System.out.println(("结果为:" + in.readLine()));        } catch (Exception e) {            e.printStackTrace();        } finally {            if (in != null) {                try {                    in.close();                } catch (IOException e) {                    e.printStackTrace();                }                in = null;            }            if (out != null) {                out.close();                out = null;            }            if (socket != null) {                try {                    socket.close();                } catch (IOException e) {                    e.printStackTrace();                }                socket = null;            }        }    }}

测试代码

public class Test {    public static void main(String[] args) throws InterruptedException {        //运行服务器        new Thread(new Runnable() {            @Override            public void run() {                try {                    BIOServer.start();                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();        //防止用户端先于服务器启动前执行代码        Thread.sleep(100);        final char[] op = {'+', '-', '*', '/'};        final Random random = new Random(System.currentTimeMillis());        new Thread(new Runnable() {            @Override            public void run() {                while (true) {                    //随机产生算术表达式                    String expression = random.nextInt(10) + "" + op[random.nextInt(4)] +                            (random.nextInt(10) + 1);                    Client.send(expression);                    try {                        Thread.sleep(random.nextInt(1000));                    }catch (InterruptedException e){                        e.printStackTrace();                    }                }            }        }).start();    }}

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » One BIO Demo

发表回复