当前位置 博文首页 > 沉默王二:BIO

    沉默王二:BIO

    作者:[db:作者] 时间:2021-07-05 16:28

    前言:今天在学习netty,看了BIO一章,内容也非常的简单,书中的例子也非常的简单,我又把其中的代码敲了一遍,感觉虽然简单,却受益匪浅,使我对阻塞同步式IO有了更清晰的认知。

    经典的BIO例子,就是有一个服务端,负责监听客户端连接,然后为每一个客户端建立线程,处理客户端的请求,处理完成后销毁。

    通过代码,我们就可以看出来,同步阻塞IO的弊端就是当客户端连接数膨胀后,系统的性能将会急剧下降,因为为每一个客户端开启一个线程,然后处理完成一个请求关闭,将会造成大量的内存垃圾。

    package com.honzh.mwq.bio.server;
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    import com.honzh.mwq.bio.server.handler.TimeServerHandler;
    
    public class TimeServer {
    	
    	public static void main(String[] args) {
    		ServerSocket server = null;
    		
    		try {
    			server = new ServerSocket(9901);
    			System.out.println("server running at port: " + 9901);
    
    			Socket socket = null;
    			while (true) {
    				socket = server.accept();
    				
    				new Thread(new TimeServerHandler(socket)).start();
    			}
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (server != null) {
    				System.out.println("server close");
    				try {
    					server.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    				server = null;
    			}
    		}
    		
    		
    	}
    }
    

    ?上类创建一个server对象,等待客户端连接,在接收到客户端连接后,启动一个线程进行socket处理。

    package com.honzh.mwq.bio.server.handler;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    
    public class TimeServerHandler implements Runnable{
    	private Socket socket;
    	
    	private BufferedReader br = null;
    	private PrintWriter pw = null;
    	
    	public TimeServerHandler(Socket socket) {
    		this.socket = socket;
    	}
    	
    	@Override
    	public void run() {
    		try {
    			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    			pw = new PrintWriter(socket.getOutputStream(), true);
    			
    			while (true) {
    				String order = br.readLine();
    				
    				if (order != null) {
    					System.out.println("the order is: " + order);
    					
    					if (order.equals("query")) {
    						pw.println(System.currentTimeMillis());
    					}
    				} else {
    					break;
    				}
    			}
    		} catch (Exception e) {
    			if (br != null) {
    				try {
    					br.close();
    				} catch (IOException e1) {
    					e1.printStackTrace();
    				}
    			}
    			
    			if (pw != null) {
    				pw.close();
    				pw = null;
    			}
    			
    			if (socket != null) {
    				try {
    					socket.close();
    					socket = null;
    				} catch (IOException e1) {
    					e1.printStackTrace();
    				}
    				
    			}
    		}
    	}
    
    }
    

    ?上类也非常的简单,线程启动后,获取客户端socket请求,如果请求到数据,则进行处理,等消息都处理完成后退出循环,然后等待资源回收。

    package com.honzh.mwq.bio.client;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class TimeClient {
    	public static void main(String[] args) {
    		Socket socket = null;
    		BufferedReader br = null;
    		PrintWriter pw = null;
    		
    		try {
    			socket = new Socket("127.0.0.1", 9901);
    			
    			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    			pw = new PrintWriter(socket.getOutputStream(), true);
    			
    			pw.println("query");
    			
    			String result = br.readLine();
    			
    			System.out.println("now time is: " + result);
    		} catch (UnknownHostException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (br != null) {
    				try {
    					br.close();
    				} catch (IOException e1) {
    					e1.printStackTrace();
    				}
    			}
    			
    			if (pw != null) {
    				pw.close();
    				pw = null;
    			}
    			
    			if (socket != null) {
    				try {
    					socket.close();
    					socket = null;
    				} catch (IOException e1) {
    					e1.printStackTrace();
    				}
    				
    			}
    		}
    	}
    }
    

    上类启动客户端,进行socket连接,发送查询命令,然后获取处理信息,然后进行资源回收。

    ?

    总结:以上内容非常的简单,也易于理解,但是重新手写一下,加上写这篇博客,让我对此的印象会更加深刻。

    cs
    下一篇:没有了