2023-04-28 17:02:14

TCP(Transmission Control Protocol)와 UDP(User Datagram Protocol)

TCP와 UDP는 인터넷 프로토콜 스택에서 전송 계층에 위치한 프로토콜이며 두 프로토콜은 데이터 전송 방식에 차이가 있고 각각의 특징에 따라 다양한 상황에서 사용된다.

  • TCP
    • 연결 지향적 프로토콜로 데이터 전송 전에 먼저 송신자와 수신자 간에 연결을 수립
    • TCP 프로토콜은 데이터의 정확성과 순서를 보장하기 때문에 신뢰성이 중요한 어플리케이션에 주로 사용
    • TCP는 데이터를 여러개의 패킷으로 분할하여 전송하며 패킷들이 올바른 순서대로 도착한 것을 확인하고 재전송을 통해 손실된 패킷을 복구
    • 위 같은 과정으로 인해 TCP는 UDP에 비해 상대적으로 느린 전송 속도를 가짐
    • 웹 브라우징, 이메일 전송, 파일 전송 등과 같은 상황에서 TCP 사용

 

  • UDP
    • 비연결 지향적 프로토콜로 데이터를 전송하기 전에 연결을 수립하지 않음
    • UDP 프로토콜은 데이터의 정확성이나 순서를 보장하지 않기 때문에 손실이나 지연이 발생해도 문제가 되지 않는 어플리케이션에서 주로 사용
    • UDP는 패킷의 전송 속도가 빠르지만 신뢰성이 낮음
    • 실시간 음성 및 영상 통화, 스트리밍, 온라인 게임 등과 같은 상황에서 UDP 사용

 

HTTP 응답 코드

웹에서 사용하는 HTTP 응답 코드(상태 코드라고도 함)는 클라이언트가 서버에 요청을 보냈을때 서버가 해당 요청에 대한 응답을 전송하는데 사용되는데 이러한 응답 코드는 3자리 숫자로 이루어져 있다.

  • 100번대 : 요청이 수신되어 처리 중인 상태 (Informational)
  • 200번대 : 요청을 성공적으로 수신 (Seccecssful)
  • 300번대 : 추가 동작이 필요한 경우(Redirection)
  • 400번대 : 클라이언트 측에서 잘못된 요청을 보냄 (Client Error)
  • 500번대 : 서버가 정상적인 요청을 처리하지 못함 (Server Error)

 

그 중 주로 사용되는 몇가지 상태 코드로는 다음이 있다.

  • 200 : 요청을 성공적으로 처리 (OK)
  • 201 : 요청이 성공적으로 처리되어 새로운 리소스 생성 (Created)
  • 204 : 요청이 성공적으로 처리되었지만 반환할 추가 콘텐츠 없음 (No Content)
  • 400 : 클라이언트의 요청이 잘못됨 (Bad Request)
  • 401 : 인증이 필요한 요청 (Unauthorized)
  • 403 : 요청이 서버에 의해(권한) 거부 (Forbidden)
  • 404 : 요청한 리소스를 찾을 수 없음 (Not Found)
  • 500 : 서버 내부 에러 발생 (Internal Server Error)
  • 503 : 서버가 일시적으로 요청을 처리할 수 없는 상태 (Service Unabailable)

 

TCP를 활용한 Server - Client 연결 테스트

  • server.js
    • client와 server가 요청을 주고 받는 메시지는 header랑 body로 나뉨
    • header의 내용은 전달하는 메시지(응답) 정보를 전달
    • body는 전달하는 데이터의 내용이 들어 있음
// server.js

// TCP server, Client를 만들기

// net 내장 모듈가져오기
const net = require("net");

// port 설정
const PORT = 8080;

// HTTP 프로토콜 버전은 1.0 1.1 2.0이 있음

// body
// Buffer.from 메소드 : 문자열을 바이트 데이터로 변환
// HTTP 응답은 바이트 데이터로 전송되기 때문에 변환해줘야함
// body 문자열을 그대로 작성할 경우 인코딩에서 문제가 생길 수 있음
const body = Buffer.from("<div><p>Hello Nodejs</p></div>");

// header
// Connection : 클라이언트와 서버의 연결 상태
// keep-alive 속성 : 클라이언트가 다음 요청을 보낼때 까지 연결 유지
// keep-Alive : 연결유지 시간 지정 timeout=4 == 연결을 4초동안 유지하고 종료
// Content-type : 전송되는 데이터의 타입 text/html == html 타입의 데이터 전송을 의미
// Content-length : 전송되는 데이터의 길이. 데이터의 끝을 알려주는 역할
const response = `HTTP/1.1 200 OK
Connection : keep-alive
keep-Alive : timeout=4
Content-type : text/HTML
Content-length : ${body.length}

${body.toString()}
`;

// 서버 객체 생성
const server = net.createServer((client) => {
  // 클라이언트 접속 시 실행
  // setEncoding 메소드 : 인코딩 방식 설정
  client.setEncoding("utf-8");

  // 클라이언트가 데이터를 보내고 데이터를 받으면 실행되는 콜백 함수
  client.on("data", (data) => {
    // data의 타입은 buffer
    console.log(data);
    // write 메소드 : 클라이언트의 응답을 보냄
    client.write(response);
  });
  // 클라이언트와 연결이 종료되면 실행되는 이벤트
  client.on("close", () => {
    console.log("접속종료");
  });
});

// 서버에 연결됬을때
server.on("connection", () => {
  console.log("접속성공");
});

// 서버를 대기상태로 만듬
server.listen(PORT, () => {
  console.log("server on. port : " + PORT);
});

  • client.js
// client.js

// HTTP는 기본적으로 TCP 통신
// TCP 통신은 쌍방향 통신이 가능

// net 내장 모듈을 가져오기
const net = require("net");
// port의 내용을 설정해줄 객체
const config = { port: 8080 };
// connect 메소드 : tcp 소켓을 만들고 지정할 포트로 연결 시도
const socket = net.connect(config);

socket.on("connect", () => {
  // 연결되면 connect 이벤트 실행
  console.log("연결 성공");

  socket.write("데이터 전송");
});

socket.on("data", (data) => {
  // tcp 소켓에서 데이터를 받으면 콜백 함수 실행
  console.log("받은 데이터 : ", data.toString());
  // end 메소드 : 데이터를 받으면 tcp 연결 종료
  socket.end();
});

 

localhost:8080으로 접근 했을때 body에 내용이 잘 나오는 것을 확인 할 수 있다.

 

키워드는 const만 사용?

nodejs를 몇일 배우다 보니 궁금증이 생겼다. 거의 모든 변수의 키워드를 const로 쓰는 것이다. 왜 그런지 찾아보니 3가지의 이유를 찾아 볼 수 있었다.

 

  1. 불변성 : const를 사용하면 변수의 값이 변경되지 않아 코드를 이해하기 쉽고 유지보수 하기가 편함
  2. 코드의 가독성 : const를 사용하면 변수가 변경되지 않으니 코드를 읽는 사람에게 변수의 의도가 명확하게 전달
  3. 최적화 : 브라우저나 nodejs 엔진은 const를 사용하여 변수 값이 변경되지 않음을 인지하여 최적화에 도움이 되어 실행 속도 향상

 

절대적인 규칙은 아니라고 하며 단순히 const는 상수를 선언할 때 쓰는 키워드인 줄 알았는데 그로인해 실행 속도가 빨라 질 수 있다고 하니 자주 사용해야 할거 같다.

728x90