BIO(阻塞式输入输出)是指在读取输入数据的时候会一直卡(阻塞)在那里,在socket编程中会致使线程没法处理其余工做,除此以外,服务端等待accept链接也是阻塞式的,因此程序想继续执行须要建立新的线程去处理其余工做。
编程
注意socket链接并不表明链接能够被处理,链接建立后,数据处理是须要线程来工做的,固然一个进程的可链接数也不是无限大的,超过最大链接数(操做系统限制或服务端限制)会致使没法链接。网络
相似阻塞式的饭店,新客人来了至关于和饭店创建一个socket链接,这只是链接能不能吃饭还要等待服务员给你下单,固然饭店要是满了,新客人是进不去的。更糟糕的是,饭店只有一个服务员一直等着给第一个客人点菜下单,其余客人都无论。客人也存在着相似问题,为了和服务员维持这个链接,一直点菜或思考点什么菜,卡在那里。socket
----
ide
为了解决上述线程阻塞的问题,只能建立新的线程来完成其余工做,使程序得以继续执行,下面使用两个类(BioServer,BioClient)模拟一下BIO。this
public class BioServer {
private ServerSocket serverSocket;
public BioServer(int port,int backlog) throws IOException {
this.serverSocket = new ServerSocket(port,backlog);
}
private void start() throws IOException {
ExecutorService executorService = Executors.newFixedThreadPool(2);
while (true) {
Socket socket = serverSocket.accept();
System.out.println(String.format("a new client connect %s", socket.getPort()));
executorService.submit(new BioServerHandler(socket));
}
}
public static void main(String[] args) throws IOException {
new BioServer(6000,3).start();
}
}
class BioServerHandler implements Runnable {
private Socket socket;
public BioServerHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream())) {
String msg;
while ((msg = br.readLine()) != null) {
System.out.println(String.format("server receive:%s", msg));
pw.println(msg + " | " + new Date());
pw.flush();
}
} catch (IOException e) {...}
}
}spa
public class BioClient {客户端为了不阻塞读取数据,建立新线程来处理数据读取工做,在当前线程阻塞式等待系统输入数据。以上就是阻塞式网络编程BIO的demo,主要存在的问题是阻塞致使线程没法复用。
private Socket socket;
public BioClient(String host,int port) throws IOException {
this.socket = new Socket(host, port);
}
public void start() {
new Thread(()->{
try(BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))){
String msg;
while((msg = br.readLine())!=null){
System.out.println(String.format("client receive %s", msg));
}
} catch (IOException e) {...}finally {...}
}).start();
System.out.println("client enter msg: ");
PrintWriter pw;
while(true){
try {
pw = new PrintWriter(socket.getOutputStream());
pw.println(new Scanner(System.in).next());
pw.flush();
} catch (IOException e) {...}
}
}
public static void main(String[] args) throws IOException {
new BioClient("127.0.0.1",6000).start(); }}