0
点赞
收藏
分享

微信扫一扫

Netty - I/O模型之BIO

五殳师兄 2022-03-21 阅读 109



文章目录

  • ​​I/O模型的定义​​
  • ​​BIO​​
  • ​​Demo Server​​
  • ​​Demo Client​​
  • ​​Demo Run​​
  • ​​BIO 同步阻塞模型​​
  • ​​小结​​


Netty - I/O模型之BIO_BIO

I/O模型的定义

什么是I/O模型呢? 简单来说就是说用什么样的通道进行数据的发送和接收。

在Java中,共支持3种网络编程IO模式:BIO,NIO,AIO

BIO

Demo Server

package com.artisan.iomodel.bio;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author 小工匠
* @version 1.0
* @description: TODO
* @date 2021/1/16 22:23
* @mark: show me the code , change the world
*/
public class SocketServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(7777);
while (true) {
System.out.println("等待client连接....");
//阻塞方法
Socket clientSocket = serverSocket.accept();
System.out.println("已收到客户端的连接....,开始处理");
handler(clientSocket);

/*new Thread(new Runnable() {
@Override
public void run() {
try {
handler(clientSocket);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();*/
}
}

private static void handler(Socket clientSocket) throws IOException {
byte[] bytes = new byte[1024];
System.out.println("准备读取客户端发送来的数据");
//接收客户端的数据,阻塞方法,没有数据可读时就阻塞
int read = clientSocket.getInputStream().read(bytes);
System.out.println("读取ing");
if (read != -1) {
System.out.println("接收到客户端的数据:" + new String(bytes, 0, read));
}

// 向服务端发送数据
clientSocket.getOutputStream().write("HelloClient".getBytes());
// 缓冲区刷新
clientSocket.getOutputStream().flush();
}
}

Demo Client

package com.artisan.iomodel.bio;

import java.io.IOException;
import java.net.Socket;

/**
* @author 小工匠
* @version 1.0
* @description: TODO
* @date 2021/1/16 22:27
* @mark: show me the code , change the world
*/
public class SocketClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 7777);
//向服务端发送数据
socket.getOutputStream().write("HelloServer".getBytes());
socket.getOutputStream().flush();
System.out.println("向服务端发送数据结束");
byte[] bytes = new byte[1024];
//接收服务端回传的数据
socket.getInputStream().read(bytes);
System.out.println("接收到服务端的数据:" + new String(bytes));
socket.close();
}
}

Demo Run

启动 Server,

Netty - I/O模型之BIO_客户端_02

然后启动Client

Netty - I/O模型之BIO_java_03

同时看下Server的数据

Netty - I/O模型之BIO_客户端_04

我们用cmd工具来连一下 , ​​telnet 127.0.0.1 7777​

Netty - I/O模型之BIO_BIO_05

回车,输入 ​​ctrl + ]​

Netty - I/O模型之BIO_数据_06

作为客户端发送消息

Netty - I/O模型之BIO_客户端_07

查看server是否收到

Netty - I/O模型之BIO_数据_08

BIO 同步阻塞模型

通过上面的例子,可以看到 一个客户端连接对应一个处理线程

上面的线程模型 可以看到 只有一个main线程在处理,如果当前main线程没有处理完,后,后面的请求是无法被处理的 。

Netty - I/O模型之BIO_java_09

当然了我们上面的是一个线程的, 也可以改造为多线程 。

new Thread(new Runnable() {
@Override
public void run() {
try {
handler(clientSocket);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();

就变成了下面这种模式

Netty - I/O模型之BIO_BIO_10

小结

缺点显而易见

  • read操作是阻塞操作,如果连接不做数据读写操作会导致线程阻塞,浪费资源
  • 每个请求都需要开辟一个线程去处理,开辟过多的线程势必会导致服务器资源紧张。

BIO 方式适用于连接数目比较小且固定的架构, 这种方式对服务器资源要求比较高, 但程序简单易理解。


举报

相关推荐

0 条评论