介绍
- 介绍: BIO是同步阻塞型(传统阻塞型),客户端有一个连接请求时,服务端就会开启一个线程去处理请求(对客户端进行读写),如果该连接什么都不做,会造成不必要的线程开销(可以通过线程池进行优化,)
- 适用场景: 连接数少且固定的架构, jdk1.4之前,只有这种IO模型
- 模型过程: 1.服务端通过ServerSocket绑定端口,并启动服务端,等待客户端连接(通过死循环一直在监听看是否有客户端连接上来)
- 2.客户端通过Socket与服务端进行通信,默认请情况下服务端需要对每一个客户端建立一个线程与之通信
- 3.服务端监听到连接请求,接受请求(severSocket.accept())
- 4.客户端发送信息
- 5.服务端读取信息并写回响应,释放资源(socket, 输出流, 输入流)
- 6.客户端接收到响应,释放资源(释放资源(socket, 输入流,输出流))
1.服务端
package com.io.bio2;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import static java.util.concurrent.Executors.newCachedThreadPool;
public class TimeServer {
public static final ExecutorService executorService;
static {
executorService = newCachedThreadPool();
}
public static void main(String[] args) {
tcpAccept();
}
public static void tcpAccept() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8080);
Socket socket = null;
while (true) {
System.out.println("等待客户端连接..........");
socket = serverSocket.accept();
System.out.println("客户端连接成功..........");
executorService.execute(new TimeServerHandler(socket));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (serverSocket != null && !serverSocket.isClosed()) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
处理器(为每一个客户端新开一个线程去处理)
package com.io.bio2;
import java.io.*;
import java.net.Socket;
import java.util.Date;
public class TimeServerHandler implements Runnable {
private Socket socket = null;
public TimeServerHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
InputStream inputStream = socket.getInputStream();
dataInputStream = new DataInputStream(inputStream);
String message = dataInputStream.readUTF();
System.out.println(Thread.currentThread().getName() + " 收到客户端消息:" + message);
OutputStream outputStream = socket.getOutputStream();
dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF(new Date().toString());
dataOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null && !socket.isClosed()) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
客户端
package com.io.bio2;
import java.io.*;
import java.net.Socket;
public class TtimeClient {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new Thread(() -> tcpSendMessage()).start();
}
}
public static void tcpSendMessage() {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket("127.0.0.1", 8080);
System.out.println("连接成功.........." + Thread.currentThread().getName());
OutputStream outputStream = socket.getOutputStream();
dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("我是长城" + Thread.currentThread().getName());
dataOutputStream.flush();
InputStream inputStream = socket.getInputStream();
dataInputStream = new DataInputStream(inputStream);
String message = dataInputStream.readUTF();
System.out.println("收到服务器消息:" + message);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null && !socket.isClosed()) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}