강의

멘토링

커뮤니티

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

정형민님의 프로필 이미지
정형민

작성한 질문수

기초 탄탄! 독하게 시작하는 Java Part 3(하) : 소켓과 파일 I/O

Selector를 적용한 싱글 스레드 채팅서버

08_chatServerSelector 코드 중 오류를 발견하여 문의 남깁니다.

작성

·

14

0

08_chatServerSelector 소스코드의 마지막 부분인 브로드캐스팅하는 함수 sendMessageAll에서 오류를 발견했습니다. 제공하여주신 소스 코드를 작성하고, 여러 클라이언트를 실행시켜보았습니다. 연결은 문제가 없었지만, 쓰기 부분에서 문제가 발생했습니다.

 

 private static void sendMessageAll(Selector selector,
                  SocketChannel sender, String msg) throws IOException {
        ByteBuffer msgBuffer = ByteBuffer.wrap((msg + "\n").getBytes());

        for (SelectionKey key : selector.keys()) {
            Channel channel = key.channel();
            if (channel instanceof SocketChannel) {
                SocketChannel target = (SocketChannel) channel;
                target.write(msgBuffer); // <- 문제 지점
            }
        }
    }

 

msgBuffer를 반복문을 통하여 타겟 클라이언트 채널에 쓰기를 할 때에, 첫 클라이언트에게만 메시지가 보내지는 것을 발견하였습니다. 이유는 write호출시 msgBuffer의 position이 마지막으로 이동이 되어서, 다른 클라이언트 소켓 채널에게는 빈 msgBuffer가 쓰기가 되어서 메시지가 보내지지가 않았습니다.

 

해결방법)

msgBuffer의 값을 할당받는 부분을 반복문 안쪽으로 이동시켜 매 이터레이션 마다 값을 받게 코드를 수정하였습니다.

  // 브로드캐스팅 함수
    private static void sendMessageAll(Selector selector, SocketChannel sender, String msg) throws IOException {

        for (SelectionKey key : selector.keys()) {
            Channel channel = key.channel();

            if (channel instanceof SocketChannel) {
                SocketChannel target = (SocketChannel) channel;

                ByteBuffer msgBuffer = ByteBuffer.wrap((msg + "\n").getBytes());

                target.write(msgBuffer);
            }
        }
    }

 

 

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다. 정형민님,

sendMessageAll 함수에서 발생한 문제에 대한 설명과 해결 방법을 알려주셔서 감사합니다. 문제는 ByteBuffer의 포지션이 write 호출 후 끝으로 이동하면서 발생한 것입니다. ByteBuffer는 데이터가 쓰인 후에도 포지션을 유지하므로, 여러 클라이언트에게 메시지를 보내려면 ByteBuffer를 반복문 내부에서 재생성하여 초기화해주는 것이 필요합니다.

해결 방법에서 제안하신대로, ByteBuffer를 반복문 안에서 새로 생성함으로써 각 클라이언트에게 올바른 메시지를 보내줄 수 있습니다. 이 방법이 적절하며, 다른 클라이언트에게도 메시지를 성공적으로 전송할 수 있게 됩니다.

유사한 문제와 해결 방법을 다룬 게시물도 확인해 보시길 추천드립니다:
- 멀티스레드 기반 서버 관련 문제 해결 방법 - 이 게시물에서는 멀티스레드와 소켓 통신 기반에서 발생할 수 있는 문제를 다룹니다.

이와 같은 접근 방법 및 개선으로 클라이언트 간 메시지 전송이 더 안정적으로 이루어질 것입니다. 소중한 피드백 감사합니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

정형민님의 프로필 이미지
정형민

작성한 질문수

질문하기