요청과 응답 이해하기1


조현영님의 Node.js 교과서의 내용을 공부하여 정리한 내용입니다.


요청과 응답 이해하기1

서버클라이언트가 있기에 동작한다.
클라이언트에서 서버요청(request)을 보내고,
서버에서는 요청의 내용을 읽고 처리한 뒤 클라이언트에게 응답(response)을 보낸다.

따라서 서버에는 요청을 받는 부분응답을 보내는 부분이 있어야 한다.
요청과 응답은 이벤트 방식이라고 생각하면 된다.
클라이언트로부터 요청이 왔을 때 어떤 작업을 수행할지 이벤트 리스너를 미리 등록해두어야 한다.

이벤트 리스너를 가진 노드 서버를 만들어보자.

이벤트 리스너를 가진 노드 서버를 만들기

1
2
3
4
5
6
7
8
// createServer.js
const http = require("http");

http.createServer((req, res) => {
// 여기에 어떻게 응답할지 적어준다.
// req 객체는 요청에 관한 정보들을,
// res 객체는 응답에 관한 정보들을 담고 있다.
});
  • http 서버가 있어야 웹 브라우저의 요청을 처리할 수 있으므로 http 모듈을 사용했다.
  • http 모듈에는 createServer 메서드가 있다.
  • 인자로 요청에 대한 콜백 함수를 넣을 수 있다.
  • 요청이 들어올 때마다 매번 콜백 함수가 실행된다.
  • 따라서 이 콜백 함수에 응답을 적어주면 된다.
  • createServer의 콜백 부분을 보면 req와 res 매개변수가 있다.
  • 매개변수 req와 res의 이름은 마음대로 바꿔도 된다.
  • 아직은 코드를 실행해도 아무 일도 일어나지 않는다.
  • 요청에 대한 응답도 넣어주지 않았고 서버와 연결하지도 않았기 때문이다.

아래 예제에서 응답을 보내는 부분과 서버 연결 부분을 추가해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// server1-0.js
const http = require("http");

http
.createServer((req, res) => {
// res 객체에는 res.write와 res.end 메서드가 있다.
// 우선 res.write의 첫 번째 인자는 클라이언트로 보낼 데이터이다.
// 지금은 HTML 모양의 문자열을 보냈지만 버퍼를 보낼 수도 있다.
// 또한, 여러 번 호출해서 데이터를 여러 개 보내도 된다.
res.write("<h1>Hello Node!</h1>");
// res.end는 응답을 종료하는 메서드이다.
// 만약 인자가 있다면 그 데이터도 클라이언트로 보내고 응답을 종료한다.
// 따라서 위의 예제는 res.write에서 <h1>Hello Node!</h1> 문자열을 한 번
// res.end에서 <p>Hello Server!</p> 문자열을 한 번 클라이언트로 보낸 후
// 응답이 종료된 것이다.
// 브라우저는 응답 내용을 받아서 렌더링한다.
res.end("<p>Hello Server!</p>");
})
.listen(8080, () => {
console.log("80번 포트에서 서버 대기 중입니다!");
});
server.on("error", error => {
console.error(error);
});
  • createServer 메서드 뒤에 listen 메서드를 붙이고
    클라이언트에게 공개할 포트 번호와 포트 연결 완료 후 실행될 콜백 함수를 넣어준다.
  • 이제 이 파일을 실행하면 서버는 8080 포트에서 요청이 오기를 대기한다.

  • listen 메서드에 콜백 함수를 넣는 대신, 다음과 같이 서버에 listening 이벤트 리스너를 붙여도 된다.

  • 추가로 error 이벤트 리스너도 붙여 보았다.
1
2
3
// console
$ node server1
8080번 포트에서 서버 대기 중입니다!

콘솔에 위와 같은 문장이 나왔다면, 이제 인터넷 브라우저를 열어
http://localhost:8080 또는 http://127.0.0.1:8080에 접속하자.

localhost와 포트란

  • localhost현재 컴퓨터의 내부 주소를 가리킨다.
  • 외부에서는 접근할 수 없고 자신의 컴퓨터에서만 접근할 수 있다.
  • 따라서 서버 개발 시 테스트용으로 많이 사용된다.
  • localhost 대신 127.0.0.1을 주소로 사용해도 같습니다.
  • 이러한 숫자 주소를 IP라고 부른다.
  • 포트서버 내에서 프로세스를 구분하는 번호이다.
    서버는 HTTP 요청을 대기하는 것 외에도 다양한 작업을 한다.
    데이터베이스와도 통신해야 하고, FTP 요청을 처리하기도 한다.
  • 따라서 서버는 프로세스에 포트를 다르게 할당하여 들어오는 요청을 구분한다.
  • 유명한 포트 번호로는 21(FTP), 80(HTTP), 443(HTTPS), 3306(MYSQL)이 있다.
  • 포트 번호IP 주소 뒤콜론(:)과 함께 붙여 사용한다.
  • 현재 예제에서는 80번 포트를 사용해 클라이언트 요청을 대기하고 있다.
  • 따라서 http://localhost:8080으로 접근해야 한다.
    하지만 http://gilbut.co.kr 같은 사이트들은 포트 번호를 따로 표시하지 않는다.
  • 바로 80번 포트를 사용하기 때문이다.
  • 80번 포트를 사용하면 주소에서 포트를 생략할 수 있다.
  • http://gilbut.co.kr:80으로 요청해도 길벗 홈페이지에 접속된다.
  • 이 책에서 80번 포트를 사용하지 않는 이유는 충돌을 방지하기 위해서이다.
  • 보통 컴퓨터들은 80번 포트를 이미 다른 서비스가 사용하고 있을 확률이 크다.
  • 보통 포트 하나에 서비스를 하나만 사용할 수 있으므로
    다른 서비스가 사용하고 있는 포트를 사용하려고 하면 에러가 발생한다.
  • 따라서 예제를 실행할 때는 다른 포트 번호들을 사용하고,
    실제로 배포할 때는 80번 또는 443번 포트를 사용한다.

  • 한 가지 더 알아둘 점이 있다.

  • 리눅스와 macOS에서는 1024번 이하의 포트에 연결할 때 관리자 권한이 필요하다.
  • 따라서 명령어 앞에 sudo를 붙여주어야 한다.
  • 예를 들면 node server1 대신 sudo node server1을 입력해야 한다.
  • 예제에서는 80번 포트를 사용하므로 sudo를 붙일 필요는 없습니다-
  • 다른 서비스가 사용하고 있는 포트를 사용할 경우
    Error: listen EADDRINUSE :::포트 번호 같은 에러가 발생합니다.
  • 이런 경우 그 서비스를 종료하거나, 노드의 포트를 다른 번호로 바꾸면 된다.

  • 드디어 웹 서버가 만들어졌다!

  • 페이지를 몇 개 더 만들어보자.
  • 페이지는 주소로 구별해주자.
  • 그 전에 HTML 파일을 만들어두는 것이 좋을 것 같다.
  • res.write 메서드로 한 줄씩 HTML 코드를 적는 것은 너무 비효율적이다.
  • 다행히 HTML 파일을 읽어서 전송하는 방법이 있다.
  • 다음 예제를 통해 배워보자.