강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

헬로월드님의 프로필 이미지
헬로월드

작성한 질문수

김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션

채팅 클라이언트 문의

작성

·

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;
    }
}

 

이상입니다.

확인해주시면 감사하겠습니다.

새해복 많이 받으세요!

 

 

답변 1

0

안녕하세요. 헬로월드님, 공식 서포터즈 David입니다.

구현하는 부분의 강의를 들으신 후, 코드를 한 번 더 살펴보시고 그리고 나서 이해되지 않는 부분을 조금 더 자세히 알려주시면 좋을 것 같습니다:)

감사합니다.

헬로월드님의 프로필 이미지
헬로월드

작성한 질문수

질문하기