3장_ 코드 이해: WebServer 클래스

2026. 1. 29. 17:33·Book/자바 웹 프로그래밍 Next Step

 

실습으로 진행할 HTTP 웹 서버의 핵심이 되는 코드는 webserver패키지의 WebServer와 RequestHandler 클래스이다.

 

먼저 이 WebServer 클래스는 “웹서버”라기보다는 정확히는

  • 특정 포트에서 TCP 연결을 받는 프로그램
  • 연결이 들어오면, 그 연결(Socket)을 넘겨서 요청/응답 처리를 다른 쓰레드로 맡기는 프로그램

이다.

즉, 여기서는 “서버가 접속을 받는 역할”까지만 담당하고, 실제 HTTP 처리는 RequestHandler가 한다.

public class WebServer {
    private static final Logger log = LoggerFactory.getLogger(WebServer.class);
    private static final int DEFAULT_PORT = 8080;

    public static void main(String args[]) throws Exception {
        int port = 0;
        if (args == null || args.length == 0) {
            port = DEFAULT_PORT;
        } else {
            port = Integer.parseInt(args[0]);
        }

        // 서버소켓을 생성한다. 웹서버는 기본적으로 8080번 포트를 사용한다.

        try (ServerSocket listenSocket = new ServerSocket(port)) {
            log.info("Web Application Server started {} port.", port);

            // 클라이언트가 연결될때까지 대기한다.
            Socket connection;
            while ((connection = listenSocket.accept()) != null) {
                RequestHandler requestHandler = new RequestHandler(connection);
                requestHandler.start();
            }
        }
    }
}

이게 전체 코드이고 하나씩 살펴 보겠다.

 

 

main()에서 하는 첫 번째 일: 포트 결정

int port = 0;
if (args == null || args.length == 0) {
    port = DEFAULT_PORT;
} else {
    port = Integer.parseInt(args[0]);
}

의미

  • 프로그램 실행할 때 포트를 안 주면 → 기본 8080
  • 실행할 때 포트를 주면 → 그 숫자를 포트로 사용

예:

  • java webserver.WebServer → 8080 사용
  • java webserver.WebServer 7070 → 7070 사용

여기서 7070이 main의 args로 들어간다.

여기서 args는 “명령줄 인자”이다. args[0]은 첫 번째 인자(포트번호)이다.

 

 

서버가 “열리는” 핵심: new ServerSocket(port)

try (ServerSocket listenSocket = new ServerSocket(port)) {
    ...
}

ServerSocket은?

  • 서버 쪽에서 쓰는 소켓으로,
  • “이 포트로 들어오는 연결 요청을 받겠다” 라고 OS에 등록하는 것이다.

쉽게 말하면:

  • 내 서버의 8080번 문 앞에 “대기 직원”을 세우는 것이다.
  • 이 순간부터 외부에서 http://IP:8080 같은 접속이 들어올 수 있는 “입구”가 열린다.

왜 try-with-resources?

  • try (...) {} 형태는 블록이 끝나면 자동으로 close() 해준다.
  • 서버가 종료될 때 포트/소켓이 깔끔하게 정리되게 하는 안전장치이다.

try-with-resources란

try ( ... ) { ... } 괄호 안에 닫아야 하는 자원을 선언하는 형태를 “try-with-resources”

 

 

서버 시작 로그

log.info("Web Application Server started {} port.", port);

 

  • “서버가 어느 포트에서 열렸는지” 로그로 남긴다.
  • 실제로 운영에서 이런 로그는 매우 중요하다(포트/환경 확인).

 

 

 

이 코드의 핵심: accept 루프

Socket connection;
while ((connection = listenSocket.accept()) != null) {
    RequestHandler requestHandler = new RequestHandler(connection);
    requestHandler.start();
}

1) listenSocket.accept()가 하는 일

  • 클라이언트가 연결을 시도할 때까지 기다린다.
  • 기다리는 동안 아무것도 안 하고 “멈춰있는 상태”가 된다. (이걸 블로킹이라고 합니다)
  • 연결이 들어오면, Socket 객체를 하나 만들어서 반환한다.

즉,

  • ServerSocket: “문(포트)”
  • accept(): “손님이 오면 문 열고 들여보내기”
  • Socket connection: “그 손님과 1:1로 통신하는 전화선/대화 채널”

중요한 점: accept()는 ‘요청 한 건(HTTP 한 번)’을 받는 게 아니라 ‘연결(connection)’을 받는 것이다.
HTTP는 그 연결 위에서 흐르는 데이터(요청/응답)일 뿐이다.

2) while을 왜 돌리나?

서버는 딱 한 명만 받고 끝나는 프로그램이 아니라,

  • 손님이 오면 받고,
  • 또 오면 받고,
  • 계속 받아야 하니까

무한 루프 형태로 “계속 accept” 하는 것이다.

여기서 accept()는 보통 절대 null을 주지 않는다.
그래서 ( ... ) != null은 사실상 “계속 돌아라”에 가까운 관용적 코드이다.

 

 

연결을 받으면 “처리 담당자”에게 넘긴다: RequestHandler

RequestHandler requestHandler = new RequestHandler(connection);
requestHandler.start();

의미

  • 방금 연결된 손님(connection)을 RequestHandler에게 넘기고
  • start()로 실행을 시작

여기서 궁금한점:

(1) 왜 RequestHandler를 새로 만들어?

  • 클라이언트 접속 하나당 Socket이 하나 생기고,
  • 그 Socket을 처리할 담당자가 필요하니까 “한 접속당 한 핸들러”로 만든다.

(2) 왜 start()를 호출해?

  • RequestHandler는 Thread를 상속한 클래스라서,
  • start()를 호출하면 새 쓰레드에서 run()을 실행하게 된다.

즉,

  • 메인 쓰레드(현재 while 루프 돌고 있는 쓰레드)는 다시 accept()로 돌아가서 다음 접속을 받을 준비
  • 동시에, 새로 생성된 쓰레드는 그 접속(Socket)을 가지고 요청 처리/응답 전송을 수행

이 구조가 없으면 어떤 문제가 생기냐면:

  • 한 클라이언트 처리하는 동안 다음 클라이언트 접속을 못 받거나, 서버가 느려진다.

 

 

정확히 이해해야 하는 포인트 3개

  1. 포트는 프로그램 실행 인자(args)로 바꿀 수 있고, 기본은 8080이다.
  2. ServerSocket은 ‘연결을 받는 문’이고, accept()는 연결이 올 때까지 기다렸다가 Socket을 준다.
  3. Socket을 받으면 RequestHandler에게 넘기고, start()로 새 쓰레드에서 처리한다.

 

 

“HTTP는 어디서 시작?”

이 파일에서는 HTTP가 아직 시작 안 했음.

  • 여기서는 TCP 연결을 받고
  • HTTP 요청 읽고/응답 쓰는 건 RequestHandler에서 시작

 

 

 


출처 : 《자바 웹 프로그래밍 Next Step》, 박재성, 로드북

'Book > 자바 웹 프로그래밍 Next Step' 카테고리의 다른 글

3장_ 요구사항1: index.html 응답하기  (0) 2026.01.30
3장_ 코드 이해: RequestHandler 클래스  (0) 2026.01.29
3장_ 소스코드 재배포  (0) 2026.01.29
3장_ 방화벽 설정  (0) 2026.01.29
3장_ 원격 서버 띄우기  (0) 2026.01.29
'Book/자바 웹 프로그래밍 Next Step' 카테고리의 다른 글
  • 3장_ 요구사항1: index.html 응답하기
  • 3장_ 코드 이해: RequestHandler 클래스
  • 3장_ 소스코드 재배포
  • 3장_ 방화벽 설정
sqaxe1
sqaxe1
woojoo-devlog 님의 블로그 입니다.
  • sqaxe1
    Woojoo's Devlog
    sqaxe1
  • 전체
    오늘
    어제
    • 분류 전체보기 (148)
      • Backend (9)
        • Servlet (7)
        • Spring (2)
      • Frontend (1)
      • CS (0)
      • Book (33)
        • 자바 웹 프로그래밍 Next Step (30)
        • 테스트 주도 개발: 고품질 쾌속개발을 위한 TDD.. (1)
        • 성공과 실패를 결정하는 1%의 네트워크 원리 (2)
      • Engineering (0)
        • Testing (0)
      • Infra (6)
        • AWS (6)
      • Java (4)
      • Network (1)
      • 김영한 (28)
        • 자바 입문 (8)
        • 실전 자바 - 기본편 (6)
        • 실전 자바 - 중급편 (10)
        • 실전 자바 - 고급편 (4)
      • Web (39)
        • Web Basics (39)
      • Project (24)
        • NeoSquare (0)
        • Memo Evolution (24)
      • 정보처리기사 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    개발서적
    aws
    java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
sqaxe1
3장_ 코드 이해: WebServer 클래스
상단으로

티스토리툴바