작성
·
105
·
수정됨
0
안녕하세요. 채팅 클라이언트 실습전에 먼저 구현을 해보았는데요.
클라이언트 메인에서 스레드를 스타트 하면 그 즉시 소켓이 닫히면서 프로그램이 종료되는 오류를 겪었습니다.
이는 클라이언트 메인에서 sender 스레드를 join하면서 해결하긴 했는데요.
영한님의 예제에서는 start() 만 하여도 프로그램이 종료되지 않는데, 왜 저의 코드는 종료될까.... try with resources 가 문제인가 싶다가도 그건 아닐거 같은 모호한 상황에 놓여서....
제가 볼 땐 도무지 보이지 않아서, 코드 리뷰와 원인 파악을 부탁드리려고 질문을 남깁니다.
MessageHandler.java
package com.hoonjin.study.java.ionetwork.network.chat.client;
import lombok.RequiredArgsConstructor;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import static com.hoonjin.study.java.util.MyLogger.log;
@RequiredArgsConstructor
public class MessageHandler implements Runnable {
private final Socket socket;
@Override
public void run() {
try (DataInputStream dis = new DataInputStream(socket.getInputStream())) {
while (true) {
String msg = dis.readUTF();
log(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
MessageSender.java
package com.hoonjin.study.java.ionetwork.network.chat.client;
import com.hoonjin.study.java.ionetwork.network.chat.Command;
import lombok.RequiredArgsConstructor;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Arrays;
import java.util.Scanner;
import static com.hoonjin.study.java.util.MyLogger.log;
@RequiredArgsConstructor
public class MessageSender implements Runnable {
private static final String DELIMITER = "\\|";
private final Socket socket;
private boolean joined = false;
@Override
public void run() {
Scanner scanner = new Scanner(System.in);
try (DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
while (true) {
log("input message with cmd: ");
String msg = scanner.nextLine();
if (msg.isEmpty()) {
continue;
}
String[] split = msg.split(DELIMITER);
String cmd = split[0];
if (Arrays.stream(Command.values()).noneMatch(c -> c.value().equals(cmd))) {
log("wrong command");
continue;
}
if (cmd.equals(Command.EXIT.value())) {
dos.writeUTF(msg);
joined = false;
break;
} else if (cmd.equals(Command.JOIN.value())) {
joined = true;
}
if (joined) {
dos.writeUTF(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ChatClient.java
package com.hoonjin.study.java.ionetwork.network.chat.client;
import java.io.IOException;
import java.net.Socket;
public class ChatClient {
private static final String SERVER = "localhost";
private static final int PORT = 23456;
public static void main(String[] args) throws IOException, InterruptedException {
try (Socket socket = new Socket(SERVER, PORT)) {
Thread messageHandler = new Thread(new MessageHandler(socket));
Thread messageSender = new Thread(new MessageSender(socket));
messageHandler.start();
messageSender.start();
messageSender.join(); // 이 부분이 없으면 시작하자마자 즉시 종료됨
} catch (IOException e) {
e.printStackTrace();
}
}
}
Command.java
package com.hoonjin.study.java.ionetwork.network.chat;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public enum Command {
JOIN("/join"),
MESSAGE("/message"),
CHANGE("/change"),
USERS("/users"),
EXIT("/exit")
;
private final String value;
public String value() {
return value;
}
}
이상입니다.
확인해주시면 감사하겠습니다.
새해복 많이 받으세요!