首页 > 编程学习 > java bio_Java BIO模型

java bio_Java BIO模型

发布时间:2022/1/17 12:25:49

前面介绍了IO的分类和区别,本文将实现一个输入字符表达式,输出算术结果的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();

}

}

8bb5dd9e3202


本文链接:https://www.ngui.cc/51cto/show-321.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000