BIO

4829 단어 bio
선언: 오늘 넷티를 공부하면서 BIO 1장을 봤는데 내용도 아주 간단했다. 책의 예도 매우 간단했다. 나는 그 중의 코드를 다시 한 번 두드렸는데 간단하지만 수익이 적지 않아서 동기식 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;
			}
		}
		
		
	}
}

상류는 서버 대상을 만들고 클라이언트 연결을 기다리며 클라이언트 연결을 받은 후 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 연결을 하며 조회 명령을 보내고 처리 정보를 얻은 다음에 자원 회수를 합니다.
 
총괄: 상기 내용은 매우 간단하고 이해하기 쉽지만 다시 손으로 쓴 다음에 이 블로그를 쓰면 저는 이에 대한 인상이 더욱 깊어질 것입니다.

좋은 웹페이지 즐겨찾기