-
요구사항 0
Socket 통신 구현
Socket 열어두고,
클라이언트 요청 대기.
TCP/IP 계층 통신-
main 메서드에서 서버 소켓을 열어두고, 연결을 기다린다.
-
연결이 되면(즉 url을 통해 8080 포트로 요청이 오면)
해당 서버는 inputStream으로 요청을 읽고,
outputStream으로 요청에 대한 응답을 하는 것이다. -
현재 이 소스는 연결이 되면, 요청을 읽고, 응답하는 부분은
스레드로 구현이 되어 있기 때문에 accept()가 실행되고,
스레드를 start() 한 뒤, 요청을 읽어 응답 메세지를 만들고
응답을 하게 된다. -
핵심은 main 실행 시을 서버를 열어두고 기다린다는 점,
기다리고 있다가 내가 url로 localhost:8080으로
접속하면, 즉 클라이언트로부터 요청이 오면
accept() 메서드가 실행되어 요청에 응답하기 위한
로직을 스레드로 수행하게 된다. -
그리고 요청에 응답하는 로직은 inputStream으로
해당 요청을 읽어들이고, outputStream으로
해당 요청에 대한 응답을 진행하게 된다. -
요청에 대한 응답은 크게는 헤더와 바디로 나눌 수 있다.
시작라인은 http 버전과 응답코드, 짧은 단어로 이루어진다.
그 밑에 헤더는 contentType과 Content-length로 이뤄진다. -
그리고 아래는 http body가 들어가는데 여기에 정적 데이터가 들어가게 된다.
-
-
요구사항 1
클라이언트의 요청을 받으면
요청 메시지의 첫 번째 줄을
추출해 요청에 맞는 html 파일로
요청에 대한 응답 처리-
클라이언트의 요청이 byte 단위로 InputStream으로 들어오는데
이를 읽어들여 요청에 맞는 응답을 처리하는 것 -
http 요청 메세지 첫 줄에 메서드(GET, POST)와
요청 url, http 스팩이 들어있다. -
요청 url을 추출해 거기에 맞는 정적 데이터를 선택해 서빙한다.
-
즉 우리가 크롬 url 창에 주소를 치면, 어떤 서버든
해당 url을 분석해서 거기에 알맞는 데이터를 보내주는 것이다. -
그리고 html과 css, javascript 등 화면을 보여주는 요소들 역시
모든 요청을 url에 할 수 없으니, ui를 만들어 url 요청을 편하게
할 수 있도록 지원해 주는 것이다. -
결국 모든 요청은 url 정보를 기반으로 서버에 요청하게 된다.
-
이를 수신한 서버는 url 정보 + 여러 메시지를 조합해 요청한 쪽으로
알맞는 응답을 하게 된다. -
왜 byte로 데이터를 주고 받는가?
-
기본적으로 모든 데이터는 byte 단위로 송수신되어 진다.
-
http 요청 메시지 역시 byte로 변환되어 inputStream을 타고
들어오게 된다. -
그래서 inputStream 안에 있는 byte로 나뉜 데이터를 BufferedReader로
한 번에 한 줄씩, 문장 단위로 읽어 온 것이다.
-
-
요구사항 2
회원가입 시 GET으로 데이터 전송
GET으로 전송 시 url에 키=값 형태로
& 구분자를 통해 전송.
요청 처리 시 첫 줄에 url과 같이
데이터 들어옴.-
GET으로 데이터를 전송하면,
url에 키 - 밸류 형태로 & 구분자를 통해
http 헤더에 실려 전송된다. -
대부분 GET 메서드는 조회에 사용되고,
데이터의 전송이나 수정은 POST를 사용한다. -
GET 요청의 특징은 url에 데이터가 같이
전송된다는 점이다. url을 통해 어떤 요청이
서버로 전송 됬는지 알 수 있다.
-
-
요구사항 3
POST로 회원가입 정보 전달해서
http 바디에서 데이터를 꺼내 저장한다.-
원인을 알았으면, 빠르게 해결하기 위해
행동하자. 알면서도 가만히 있지 말자. -
삽질 역시 시간을 정해 두고 해야 한다.
-
마냥 낭비하는 습관을 없애자.
빠르게 문제를 해결할 수 있는 방법을
동원해서 문제를 해결하고, 추후에 리팩토링 하자. -
일단 구현에 초점을 맞추고, 반드시 돌아와
리팩토링 하자. 요구사항은 충족해야 한다. -
POST는 헤더에는 아무런 데이터가 없다.
헤더 이후 한 줄 공백 후 데이터가 담겨 온다. -
BufferedReader의 경우 한 줄 읽기와, 문자 하나 읽기가 있는데
문자를 하나씩 읽을 경우엔 다 읽으면 버퍼링이 없다. -
하지만 한 줄 씩 읽을 땐 버퍼링이 발생하는데...정확한 원인은
모르겠다. 내가 잘못한건지, 아니면 무한정 기다리고 있는건지.
한 줄 씩 읽을 땐 유의하자.
-
-
처음에 Socket을 통해 8080 port를 열어두고 기다린다.
-
내가 localhost:8080을 브라우저에 요청한다.
-
8080을 열어둔 내가 만든 Socket 서버가 응답하면서
스레드를 실행시킨다. 해당 스레드를 통해
클라이언트의 요청을 받을 수 있고, 알맞는 응답을 한다. -
회원가입 버튼을 누르는 행동 역시 서버에게 요청한 것이다.
서버는 회원가입 버튼을 눌렀을 때 이동하는 html 파일을
outputStream을 통해 byte로 변환해 응답한다. -
브라우저는 이를 해석해 클라이언트에게 보여주게 된다.
-
회원가입을 하기 위해 데이터를 입력하고 클라이언트는 다시
버튼을 눌러 요청을 하게 된다. -
이 때 요청은 POST로 처리된다. 그렇게 되면 url에는 데이터가
표시되지 않고, http body에 데이터가 담겨 서버에 전송된다. -
http 헤더에 POST 메서드를 확인하고, 데이터를 축출한다.
-
해당 데이터를 저장한다.
-
요구사항 4
회원가입 시 따로 보여줄 화면이 없으니
302 상태 코드를 전송 후 응답 역시
index.html로 응답한다.-
상태코드는 1xx ~ 5xx까지 있다.
-
각각의 상태코드는 응답 시 상태를 의미하는데
1xx는 처리중이라는 코드, 2xx는 응답 성공시,
3xx는 리다이렉트를 의미하는 코드, 4xx는 클라이언트의
잘못된 요청을 의미한다. 5xx는 서버의 문제로 정상적인
응답이 불가능 할 때 보이는 상태코드이다. -
서버는 응답 시 현재 상태에 알맞는 상태코드를
클라이언트에 보낼 의무가 있다? 보내야 한다? -
mvc 방식에서는 개발자가 직접 응답을 작성하지 않지만
restAPI 방식에서는 개발자가 직접 응답을 데이터와
메시지를 작성하기 때문에 작성 방법이나, 코드는 알고
있으면 좋을 듯 하다.
-
-
요구사항 5
로그인 구현 후 로그인 시
해당 유저의 쿠키값을 응답헤더에
넣어 전송하는 것이다.-
html form 태그에서 action으로 요청하는 값은
url이다. 해서 html을 어떤 파일을 보내든
거기에 적은 값이 url에 남게 된다. -
내가 보내는 html 파일이 url에 남는것이 아니라
요청한 값이 그대로 url에 남기 때문에 get일 때,
post일 때, 그리고 다른 http 메서드를 사용할 때
url이 같아도 된다. 메서드로 구분하기 때문. -
거기에 요청이 들어오면, http 메서드로 나누고,
그 다음 안에 있는 값을 꺼내 사용하는 것이다. -
쿠키는 헤더에 Set-Cookie: 쿠키이름=쿠키값
이렇게 문자열로 쿠키값을 클라이언트에 전송하면
클라이언트는 이 값을 보관 하면서 요청을 할 때 마다
해당 쿠키 값을 보내게 된다. -
그럼 서버에서는 쿠키가 필요하면 이 값을 사용하고,
아니면 무시하는 쪽으로 해서 쿠키를 사용한다.
-
-
요구사항 6
로그인 시 쿠키값을 클라이언트에 저장한 뒤
그리고 회원정보 보기를 누르면 클라이언트에서
요청헤더에 보내온 쿠키값이 ture일 때만
회원목록을 보여주고, false라면 로그인을
하도록 한다.-
서버에서 클라이언트의 어떤 행동에 대해
쿠키를 발급하면, 그 다음 응답에서는
클라이언트 요청 헤더에 쿠키값이 담겨오게 된다. -
그리고 쿠키를 한 개 이상 보관할 수도 있다.
스프링을 사용하면 클라이언트의 어떤 행위에 대해서
쿠키를 보내 클라이언트 쪽에 저장시키고,
필요한 곳에서 메서드로 불러 사용할 수 있을듯 하다. -
쿠키는 이름과 값을 맵핑해서 저장한다.
해당 이름을 통해 값을 뽑아낼 수 있을 거 같다.
응답할 때 한 번 보내 클라이언트에 저장하면,
그 이후론 클라이언트가 요청에 자동으로
포함시켜 보내온다.
-
확실히 코드를 나누는게 힘들다.
비슷한 기능을 하는 로직을 묶어
객체로 만들 수 있을 거 같은데
내일 좀 더 고민해 봐야겠다.
확실히 이렇게 만들면서 공부하니까
이론적으로만 알던 개념들을 더 잘
이해하게 됬고, 명확해졌다.
항상 배우고자 하는 개념이 있다면
뭐든 만들어 보면서 배우자.