08. TCP 프로그래밍
02. 에코 클라이언트/서버 프로그래밍.
에코는 말 그대로 메아리를 의미한다. 클라이언트가 보낸 데이터를 서버 쪽에서 받아들여, 클라이언트에게 그대로 다시 보내주는 것을 의미한다.
에코 서버
- 1001번 포트에서 동작하는 ServerSocket을 생성한다.
- ServerSocket의 accept() 메소드를 실행해서 클라이언트의 접속을 대기한다.
- 클라이언트가 접속할 경우 accept() 메소드는 socket 객체를 반환한다.
- 반환 받은 Socket으로부터 InputStream과 OutputStream을 구한다.
- InputStream은 BufferedReader 형식으로 변환하고OutputStream은 PrintWriter 형식으로 변환한다.
- BufferedReader의 readLine() 메소드를 이용해서 클라이언트가 보내는 문자열 한줄을 읽어 들인다.
- 6에서 읽은 문자열을 PrintWriter에 있는 println()을 이용해 다시 클라이언트로 전송한다.
- 6,7 작업을 반복한다. 클라이언트가 접속을 종료하게 되면 BufferedReader에 있는 readLine은 null을 반환한다.
- IO 객체와 소켓의 Close() 메소드를 호출한다.
에코 클라이언트
- Socket 생성자에 서버의 IP와 서버의 동작 포트 값(10001)을 인자로 넣어 생성한다. 소켓이 성공적으로 생성되었다면, 서버와 접속이 성공적으로 되었다는 것을 의미한다.
- 생성된 Socket으로부터 InputStream과 OutputStream을 구한다.
- InputStream은 BufferedReader 형식으로 변환하고 OutputStream은 PrintWriter 형식으로 변환한다.
- 키보드로부터 한 줄씩 입력 받는 BufferedReader 객체를 생성한다.
- 키보드로부터 한 줄을 입력 받아 PrintWriter에 있는 println()메소드를 이용해서 서버에게 전송한다.
- 서버가 다시 반환하는 문자열을 BufferedReader에 있는 readLine() 메소드를 이용해서 읽어 들인다. 읽어 들인 문자열은 화면에 출력한다.
- 4, 5, 6을 키보드로부터 quit 문자열을 입력 받을대까지 반복한다.
- 키보드로부터 quit 문자열이 입력되면 IO 객체와 소켓의 close() 메소드를 호출한다.
import java.net.*;
import java.io.*;
public class EchoClient{
public static void main(String[] args){
try{
Socket sock = new Socket("127.0.0.1", 10001);
BufferedReader keyBoard = new BufferedReader(new InputStreamReader(System.in));
OutputStream out = sock.getOutputStream();
InputStream in = sock.getInputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = null;
while((line = keyBoard.readLine()) != null){
if(line.equals("quit")) break;
pw.println(line);
pw.flush();
String echo = br.readLine();
System.out.println("서버로부터 전달받은 문자열 :" +echo);
}
pw.close();
br.close();
sock.close();
}catch (Exception e){
System.out.println(e);
}
}
}
import java.net.*;
import java.io.*;
public class EchoServer{
public static void main(String[] args){
try{
ServerSocket serverSocket = new ServerSocket(10001);
System.out.println("접속을 기다립니다....");
Socket sock = serverSocket.accept();
InetAddress inetAddr = sock.getInetAddress();
System.out.println(inetAddr.getHostAddress() + " 로 부터 접속했습니다.");
OutputStream out = sock.getOutputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
InputStream in = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = null;
while((line = br.readLine()) != null){
System.out.println("클라이언트로 부터 전송받은 문자열 : "+line);
pw.println(line);
pw.flush();
}
pw.close();
br.close();
sock.close();
}catch (Exception e) {
System.out.println(e);
}
}
}
4. 에코 클라이언트와 에코 서버의 문제점
이 에코 서버의 문제점은 server는 하나의 클라이언트 접속만을 처리할 수 있다는 것이다. accept()로 대기하고 있다가 클라이언트의 접속 요청이 오면 클라이언트와 통신할 수 있는 소켓을 반환한 후, 다시 accept()하지 않기 때문이다.
출처 : 김성박 송지훈 공저, 『 자바 IO & NIO 네트워크 프로그래밍』, 한빛미디어(2004.9.30), 8장 인용.