전이중 통신은 채팅 처럼 양방향에서 동시에 통신이 가능한 방식이다.
자바를 통해 채팅이 가능한 코드를 만들어보자.
1. 클라이언트 → 서버 일방적 채팅 보내기
클라이언트는 BufferedWriter 를 만들고, 서버는 BufferedReader 를 만든다. 자바는 간소화를 위해
BufferedWriter 는 PrintWriter 로 대체해서 사용할 수 있다. 반복된 채탱을 보내기 위해 while 문을 사용한다.
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 5000);
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
Scanner sc = new Scanner(System.in);
while (true) {
String msg = sc.nextLine();
pw.println(msg);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
PrintWriter 를 이용하면 new OutputStreamWriter(socket.getOutputStream()) 를 socket.getOutputStream() 로 짧게 만들 수 있다. true 는 flush() 의 역할로 반드시 필요하다.
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(5000);
Socket socket = serverSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
String reseiveMsg = br.readLine();
System.out.println("클라이언트가 보낸 메세지:" + reseiveMsg);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

서버가 클라이언트에게 여러번 메세지를 보낼 수 있다.
2. 서버 → 클라이언트 채팅 보내기
[클라이언트]
while (true) {
String msg = sc.nextLine();
pw.println(msg);
String reseiveMsg = br.readLine();
System.out.println("서버가 보낸 메세지:" + reseiveMsg);
}
[서버]
while (true) {
String reseiveMsg = br.readLine();
System.out.println("클라이언트가 보낸 메세지:" + reseiveMsg);
String msg = sc.nextLine();
pw.println(msg);
}
각 클래스의 반복문에 버퍼를 추가 했다. 실행하면 이런 결과가 나온다.

메세지 전송은 가능하지만 반복문에서 readLine 과 println 가 순서대로 출력된다.
따라서 서버나 클라이언트는 연달아서 채팅을 할 수 없고 응답이 있어야 메세지가 발송된다.
그래서 동시에 실행을 위해서는 스레드가 필요하다.
new Thread(() -> {}).start(); // 스레드 생성 방법
이 스레드를 서버와 클라이언트 클래스에 추가한다.
3. 스레드를 추가한 전이중 통신
[클라이언트]
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 5000);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
Scanner sc = new Scanner(System.in);
new Thread(() -> {
while (true) {
try {
String reseiveMsg = br.readLine();
System.out.println("서버가 보낸 메세지:" + reseiveMsg);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
new Thread(() -> {
while (true) {
String msg = sc.nextLine();
pw.println(msg);
}
}).start();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
[서버]
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(5000);
Socket socket = serverSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
Scanner sc = new Scanner(System.in);
new Thread(() -> {
while (true) {
try {
String reseiveMsg = br.readLine();
System.out.println("클라이언트가 보낸 메세지:" + reseiveMsg);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
new Thread(() -> {
while (true) {
String msg = sc.nextLine();
pw.println(msg);
}
}).start();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
코드가 완성 되었다. while 문의 코드를 각각 2개의 스레드로 만들었다. 스레드로 다중 처리가 가능하기 때문에 양방향으로 발신과 수신이 가능하다.

Share article