서버는 Client의 어떤 정보를 통해서 응답을 할까?

YoungHo-Cha·2022년 12월 25일
2

Spring

목록 보기
4/4
post-thumbnail

최근 면접에서 서버 응답에 대한 질문을 받았다. 항상 막연하게 생각만하고 있던 내용이라서 오늘 구체적으로 알아볼 예정이다.

목차

  • 서버는 응답하기 위해서 어떤 값을 알아야할까?
  • HTTP
  • Socket

서버는 응답하기 위해서 어떤 값을 알아야할까?

택배를 예시로 보자.

택배 회사에 배송요청이 들어오면 요청한 사람의 구체적인 주소를 알아야 한다. 일반적으로 사용하는 주소 체계로는 다음과 같이 생겼다.

oo도 oo시 oo구 oo동 ooo - ooo o건물 o호

행정구역으로 대분류부터 소분류까지 그리고 구체적인 건물 이름 및 공간 번호까지 나란히 나열이 되어있다.

그럼 컴퓨터 세계에서 "데이터 배송요청"이 존재할 때, 서버는 어떠한 값을 가지고 있어야 할까?

Spring에서 어떻게 동작하는지 한번 알아보자.

실행환경 구성

스프링의 실행 과정을 살펴보기 위해서 테스트 실행환경을 구축해야 한다.

Step 1 : 임의 코드 작성

스프링 실행환경을 알아보기위해서 다음과 같이 임의의 컨트롤러와 메소드를 생성해보자.


@RestController
public class TestController {
  
    @GetMapping("/hi")
    public String abc(){
        return "hi!";
    }
}

Step 2 : Break Point를 등록하고 디버그 모드로 실행하자.

Step 3 : 테스트 컨트롤러 메소드를 실행하자.

Step 4 : 디버그 모드가 정상적으로 동작하는지 확인하자.

이제 "http://localhost:8080/hi" 동작을 수행하는 흐름을 볼 준비가 끝났다.

HTTP Socket 단방향 과정 살펴보기

디버깅 모드로 하나부터 살펴보면 Request가 들어오고, Thread가 발급되어 전반적인 웹 요청-응답 흐름을 살펴볼 수 있다.

우리의 목적은 Response를 하기 위해서 Client의 정보를 저장하는 코드를 찾아야 한다.

전반적인 과정을 볼 것인데, 코드량이 너무나 많다.. 일부만 발췌하여 보자!

Step 1 : Worker Thread 할당

위의 로직에서 쓰레드를 할당하는 과정을 볼 수 있다.

Step 2 : Socket 준비

다음의 클래스에서 Socket 연결에 대한 기초작업을 할 수 있는 것을 볼 수 있다.

자세한 내부를 살펴보면 다음과 같은 작업을 하는 것을 볼 수 있다.

  1. socket 상태 확인

  2. handShake 확인

해당 Socket을 준비하는 과정 중에 요청자의 정보를 얻는 것을 볼 수 있다.

host 정보와 remoteAddr를 얻는 것을 볼 수 있다.

host 정보를 얻는 과정을 살펴보면, 다음과 같다.

getHostName을 끝까지 가보면 ip주소를 얻는다. ip 주소는 다음과 같이 얻는다.

중간에 "Native" 메소드로 os에서 ip정보를 얻어온다는 것 또한 알 수 있다.

sa는 소켓 address 데이터 저장 주소이다.

너무나 많은 정보가 있다보니까 약간 헷갈린다.. 그래서 아주 핵심적인 것만 짚어보자.

소켓은 위와 같은 정보들을 저장하고 있다.

하나씩 무엇인지 알아보자.

  • localAddr : 해당 서버의 IP 주소를 말한다.

  • localName : 해당 서버의 이름을 말한다.

  • localPort : 해당 서버의 port를 말한다.

  • remoteAddr : TCP/IP 접속 중에 생성되는 값으로, 접속자의 IP 주소를 말한다.

  • remoteHost : 접속자의 Host 이름을 말한다. (host란 네트워크에 연결된 장치에 부여되는 고유한 이름을 말한다. ip 대신 사용한다.)

  • remotePort : 접속자의 Process Port 번호를 말한다.

실제 저장 내용

실제로 어떤 값이 저장되어 있는지 확인을 해보았다.

로컬로 요청을 하였기 때문에 remoteAddr의 값이 "0:0:0:0:0:0:0:1"로 저장된 것을 볼 수 있다.

WebSocket 양방향 통신 살펴보기

여기서 말하는 Socket이란 실제로 "채팅"에 쓰이는 Socket을 말한다.

양방향 통신 또한 마찬가지의 정보를 가지고 있어야 한다.

Spring에서 제공해주는 Socket 라이브러리를 살펴보자.

위의 라이브러리를 살펴볼 예정이다.

Step 1 : 메세지를 보내거나 받은 정보에 대한 로직을 handler로 저장해놓고 task 단위로 실행한다.

여기서 Executor는 task를 실행해주는 것이다.

Step 2 : 메세지에 대한 처리를 한다.

아래와 같이 message를 "보내기 전"과 "보낸 후"로 사전 처리, 에러 처리 그리고 후 처리를 한다.

아래와 같이 message를 보낸다.

보내온 메세지의 타입에 따라 주어진 코드를 실행한다.

주어진 코드는 socket 통신의 STOMP 서브 프로토콜에 따라 수행된다.

빨간 줄로 그어진 내용은 "소켓 연결"에 해당하는 정보이다.

"sessionId"에 따라 해당하는 접속자의 정보를 map에 저장한 것을 볼 수 있다.

소켓이 연결되는 당시에는 서버는 접속자의 정보를 저장하여야 한다. 그리하여 다음의 코드를 분석해야 서버에서 접속자의 정보를 저장하는 내용을 볼 수 있다.

마치며

잘못된 내용이나 부족한 내용이 있는 느낌이 다소 있다.. 느낌만 파악했다는 것에 의미를 두자!

특히나 WebSocket의 실제 저장되는 정보를 눈으로 보고싶었는데.. 디버깅이 안되어서 찾을 수가 없었다.(WebSocket 관련 라이브러리만 2시간 넘게 살펴본 것 같다.)

profile
관심많은 영호입니다. 궁금한 거 있으시면 다음 익명 카톡으로 말씀해주시면 가능한 도와드리겠습니다! https://open.kakao.com/o/sE6T84kf

0개의 댓글