기타

[JAVA]Client-Server Socket 통신, N:1 다중 클라이언트, 멀티스레드

Noooodle 2024. 11. 5. 18:13

서버-클라이언트 연결중에, 클라이언트가 먼저 종료되면 보통 서버는 살아있다. 근데 반대로 서버가 죽은 경우에는? 클라이언트도 종료되지만, 서버가 다시 살아났을때 클라이언트가 연결할 수 있도록 해보자..

 

다중 클라이언트, 멀티스레드 환경, 클라이언트-서버 연결 중에 서버가 먼저 끝난 경우. 클라이언트 재연결 시도

 

package client;

import client.domain.*;

import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Clients {
    private static final String SERVER_ADDRESS = "localhost"; // 서버 주소
    private static final int SERVER_PORT = 12345; // 서버 포트 번호
    private static final int MILLISECOND = 1000;

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5); // 최대 5개의 동시작업 가능한 스레드 풀

        executor.execute(new TimeClient()); // 시간 클라이언트 : 1초마다 TimeInfo 객체 전송
		// .. 다른 스레드 생략 

        executor.shutdown(); // 스레드풀 종료, 현재 처리중인 작업, 작업 큐에 대기하는 모든 작업을 처리한 뒤 종료
}

static class TimeClient implements Runnable {

        @Override
        public void run() {
            do {
                try (Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
                     ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); // 직렬화&역직렬화 관련 IO
                     ObjectInputStream in = new ObjectInputStream(socket.getInputStream())) {
                    
                    System.out.println("시간 클라이언트와 뉴스 서버가 연결되었습니다.");

                    while (true) {
                        // 클라이언트 - 서버 통신 내용.. 생략
                    }
                    
                } catch (SocketException e) { // 소켓이 닫혔을때 = 즉, 서버가 실행중이 아님
                    System.out.println("뉴스 서버가 종료되었습니다.");
                } catch (InterruptedException | ClassNotFoundException | IOException e) {
                    e.printStackTrace();
                }

                // 서버 재연결 전에 잠시 기다림 -> 1.1초 안에 서버가 살아나면 다시 연결됨
                try {
                    Thread.sleep((long) (MILLISECOND * 1.1));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            } while (true); // 서버와 재연결 무한반복..
        }
    }

 

서버 코드는 생략.. 귀찮으니까

 

핵심은 클라이언트 역할을 수행하는 스레드를 socket이 종료되었다고 바로 끝내지 않고, do while문을 통해 서버 접속을 시도하는 것

소켓 연결이 끊겨서 소켓이 끝나는 것과 스레드가 끝나는 것은 다르다.. 이걸 이해못해서 고생함

 

 

실제 코드에서는 재연결 시도 횟수를 3회로 주어서 3회까지 연결해보고 안되면 스레드를 종료한다.

실제 작동 결과

'기타' 카테고리의 다른 글

Apache Tomcat 8.5.3 설치  (2) 2024.11.11
에러 일기  (1) 2024.05.19