看了一篇BIO(同步阻塞)NIO(同步非阻塞)AIO(异步非阻塞)的文章,就是非阻塞IO,大家都知道,Java中的通信是通过流进行操作的。这样就会提出几个名词。阻塞,非阻塞,同步,异步。
- 同步 - 是针对通信机制而言的,同步是指当我发送一个请求后,我代码就要等待响应,否则不能执行接来下的代码。
- 异步 - 也是针对通信机制而言的,异步是指当我发送请求后,此时我还可以去做其他的事情,当有结果返回了,它会自动调用回调函数。
- 阻塞 - 是针对线程而言的,发送一个请求后线程不去做任何其他事情,只是挂起,这样很浪费资源。
- 非阻塞 - 也是针对线程而言的,发送一个请求后线程可以去做任何其他事情。
接下来使用BIO实现了一个简单的Server和Client进行同步阻塞通信的小Demo.
代码仓库:https://github.com/maronghe/iodemo/tree/master/src/com/ibm/bio
接下来写的代码,尽最大努力去遵照《阿里巴巴Java开发手册》的规范进行编码。如果喜欢请点击一个小星星。代码尽量参照于欢迎吐槽。
启动方法是:
先运行服务端程序,再运行客户端程序。
工作原理是:
server:1 创建ServerSocket
2 监听端口,进入阻塞状态
3 创建输入输出流对象(DataInputStream,DataOutputStream)
4 读取数据(循环)
5 写回数据(循环)
client:
1 创建Socket对象
2 创建输入输出流对象(DataInputStream,DataOutputStream)
3 获取Scanner 输入信息(循环)
4 写数据(循环)
5 读数据(循环)
6 结束
Server端:
package com.ibm.bio;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* BioSocketServer
* @author Logan
*/
public class BioSocketServer {
public static void main(String[] args) {
// 创建各种空对象
ServerSocket serverSocket = null;
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
// 创建serverSocket对象,监听9000端口
serverSocket = new ServerSocket(9000);
// 监听端口 《阻塞状态》
socket = serverSocket.accept();
while (true){
// 从流中获取输入源
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
String readLine = null;
readLine = dataInputStream.readUTF();
if(readLine == null){
continue;
}
if("end".equals(readLine) || "quit".equals(readLine)){
break;
}
System.out.println("Client :" + readLine);
// 写数据
dataOutputStream.writeUTF(readLine);
}
} 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){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Client端:
package com.ibm.bio;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
* BioSocketClient
* @author Logan
*/
public class BioSocketClient {
public static void main(String[] args) {
// 创建各个空对象
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
Scanner scanner = new Scanner(System.in);
try {
// 创建socket对象
socket = new Socket("127.0.0.1",9000);
// 获取输入输出流
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
String inputLine = null;
// 读取数据
while (true){
inputLine = scanner.nextLine();
if ("end".equals(inputLine)){
break;
} else {
System.out.println("Client:" + inputLine);
// 写数据
dataOutputStream.writeUTF(inputLine);
// 读数据
String getLine = dataInputStream.readUTF();
System.out.println("Server : " + getLine);
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
// 先开的流后关闭,后开的流先关闭
if(dataInputStream != null){
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(dataOutputStream != null){
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(scanner != null){
scanner.close();
}
}
}
}