반응형

자바로 소켓 프로그램 연동 프로젝트를 구성하고 테스트를 하면서 이상한 버그를 발견하였다.

 

소켓 서버에서 클라이언트 연결을 하고 전송되는 데이터를 기다리는데 연결 클라이언트 정보 이력은 확인이 되지만, 클라이언트에서 전송한 문자열 데이터를 받지 못하고 무한 대기하는 현상이였다.

 

기존 소스

public void run(){
	BufferedReader br = null;
	PrintWriter pw = null;
	
	try{
		String connIp = socket.getInetAddress().getHostAddress();
		logger.info(StringUtils.logStr(connIp + "에서 연결 시도."));
		int BUF_SIZE = 1024*7;
		br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf8"), BUF_SIZE);
		pw = new PrintWriter(socket.getOutputStream());
		
		String receiveStr = ""; 
		String tmp = "";
		while((tmp = br.readLine()) != null) {
			receiveStr += tmp;
		}
		logger.info(StringUtils.logStr("receive msg : " + receiveStr));

위 와 같은 형태로 BufferedReader를 통해 readLine형태로 메시지를 전달받고 null일때까지 데이터를 임시 변수에 받아서 저장하는 형태였다.

 

하지만 전송하는 클라이언트에서 문자열 끝에 개행문자 "\n" 를 처리해주거나 BufferedWriter를 사용해 newLine() 처리를 해주지 않으면 영원히 머물러 있는 무한 대기 현상을 겪었고, 클라이언트측에서는 개행을 보장해주지 않는 상황이라 받는 부분을 개선해야 했다.

 

BufferedReader의  read()를 사용하여 개선하였다.

 

개선 소스

public void run(){
	BufferedReader br = null;
	PrintWriter pw = null;
	
	try{
		String connIp = socket.getInetAddress().getHostAddress();
		logger.info(StringUtils.logStr(connIp + "에서 연결 시도."));
		int BUF_SIZE = 1024*7;
		br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf8"), BUF_SIZE);
		pw = new PrintWriter(socket.getOutputStream());
		
		// 클라이언트에서 보낸 문자열 출력
		StringBuffer buffer = new StringBuffer();
		while(true) {
			int ch = br.read();
			if((ch<0) || (ch == '\n')) {
				break;
			}
			buffer.append((char) ch);
		}
		String receiveStr = buffer.toString();
		logger.info(StringUtils.logStr("receive msg : " + receiveStr));
반응형