채팅 클라이언트 문의
116
작성한 질문수 2
안녕하세요. 채팅 클라이언트 실습전에 먼저 구현을 해보았는데요.
클라이언트 메인에서 스레드를 스타트 하면 그 즉시 소켓이 닫히면서 프로그램이 종료되는 오류를 겪었습니다.
이는 클라이언트 메인에서 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;
}
}
이상입니다.
확인해주시면 감사하겠습니다.
새해복 많이 받으세요!
답변 1
RequestHandler 버전 간 process() 파라미터 차이 질문
0
76
2
리플렉션 default
0
57
1
그럼 SOURCE나 CLASS는 어떤 경우에 사용하나요?
0
83
2
네트워크 프로그램 자원종료 Socket 정리 시 closed 사용 문의
0
105
2
FileInputStream의 transferTo 사용 시 Buffer 문의
0
67
1
오타 제보 드립니다
0
76
2
강좌 복습 팁이 있으신 분들 공유해주시면 감사하겠습니다.
0
114
1
16강 질문있습니다.
0
53
1
한글이 깨질 떄 어떻게 해야 하나요?
0
83
1
자원 정리시 에러가 발생 했을 때 메모리 상황 및 실무에서 로그 확인 방법
0
96
1
인텔리제이에서 네모(스탑버튼) 누르는 것의 의미
-1
71
1
강의 섹션 8: 네드워크 -프로그램 3부분 10:45 오타?
0
90
2
제대로 이해한게 맞나 궁금합니다
0
80
1
File,Files 강의 2번쨰 Files 07:30 에 tmep 파일들을 다 지운건가요 ?
0
65
1
/.well-known/appspecific/com.chrome.devtools.json 에러에 대해서
0
639
1
Socket 자원을 정리할때 stream 을 정리하지 않는 이유가 궁금합니다.
0
95
1
클라이언트 강제종료시 오류 메세지
0
112
2
고급 2편에는 퀴즈가 없네요?
0
102
1
55. 네트워크 프로그램5 - 자원정리2 질문
0
69
1
클라이언트가 FIN과 함께 보내는 ACK는 무엇에 대한건가요?
1
111
2
BufferedInputStream이 1바이트씩 조회해도 성능이 좋은 이유
0
83
1
오타제보
0
65
2
문자 집합 호환성 여부를 판단할 때
0
55
1
utf-8, char
0
57
1





