(1)概念原理
BIO(Blocking IO) 又称同步阻塞IO
BIO API:Socket、ServerSocket
【弊端】
1.如果BIO使用单线程接受连接,则会阻塞其他连接,效率较低。
2.如果使用多线程虽然减弱了单线程带来的影响,但当有大并发进来时,会导致服务器线程太多,压力太大而崩溃。
3.就算使用线程池,也只能同时允许有限个数的线程进行连接,如果并发量远大于线程池设置的数量,还是与单线程无异。另外多线程也会有线程切换带来的消耗
4.IO代码里read操作是阻塞操作,如果连接不做数据读写操作会导致线程阻塞,就是说只占用连接,不发送数据,则会浪费资源。比如线程池中500个连接,只有100个是频繁读写的连接,其他占着浪费资源!
Tomcat( BIO )和Jetty(NIO)
(2)BIOServer
public class BIOServer {
? ? public static void main(String[] args) throws IOException {
? ? ? ? //创建服务端套接字 & 绑定host:port & 监听client
? ? ? ? ServerSocket serverSocket = new ServerSocket(9999);
? ? ? ? //等待客户端连接到来
? ? ? ? Socket socket = serverSocket.accept();
? ? ? ? //拿到输入流 -- client write to server
? ? ? ? InputStream in = socket.getInputStream();
? ? ? ? //拿到输出流 -- server write to client
? ? ? ? OutputStream out = socket.getOutputStream();
? ? ? ? while (true){
? ? ? ? ? ? //将数据读到buf中
? ? ? ? ? ? byte[] buf = new byte[32];
? ? ? ? ? ? //server read from client
? ? ? ? ? ? int len = in.read(buf);
? ? ? ? ? ? //如果len == 1,说明client已经断开连接
? ? ? ? ? ? if(len == -1){
? ? ? ? ? ? ? ? throw? new RuntimeException("连接已断开");
? ? ? ? ? ? }
? ? ? ? ? ? System.out.println("Server:" + new String(buf, 0, len));
? ? ? ? ? ? //将读出来的数据写回给client
? ? ? ? ? ? //如果不使用偏移量,可能会将buf中的无效数据也写回给client
? ? ? ? ? ? byte[] send = "hi".getBytes();
? ? ? ? ? ? out.write(send, 0, send.length);
? ? ? ? }
? ? }
}
(3)BIOClient
public class BIOClient {
? ? public static void main(String[] args) throws IOException, InterruptedException {
? ? ? ? //创建客户端套接字 & 连接服务器
? ? ? ? Socket socket = new Socket("127.0.0.1", 9999);
? ? ? ? //拿到输入流 -- server write to client, client read from server
? ? ? ? InputStream in = socket.getInputStream();
? ? ? ? //拿到输出流 -- client write to server
? ? ? ? OutputStream out = socket.getOutputStream();
? ? ? ? while (true){
? ? ? ? ? ? //client write to server
? ? ? ? ? ? byte[] send = "hello".getBytes();
? ? ? ? ? ? out.write(send);
? ? ? ? ? ? //read from server
? ? ? ? ? ? byte[] buf = new byte[32];
? ? ? ? ? ? int len = in.read(buf, 0 ,send.length);
? ? ? ? ? ? //如果len == 1,说明server已经断开连接
? ? ? ? ? ? if(len == -1){
? ? ? ? ? ? ? ? throw? new RuntimeException("连接已断开");
? ? ? ? ? ? }
? ? ? ? ? ? System.out.println("Client:" + new String(buf, 0, len));
? ? ? ? ? ? Thread.sleep(1000);
? ? ? ? }
? ? }
}