TCP 통신

이상현·2024년 10월 22일

[ TIL ]

목록 보기
29/38

TCP 통신

TCP 통신이란?

  • TCP(Transmission Control Protocol) 통신은 데이터 전송을 신뢰성 있게 처리하기 위한 프로토콜로, 주로 인터넷과 네트워크에서 사용된다.

TCP 통신의 주요 개념

  1. 연결 기반 통신
  • TCP는 데이터 전송 전에 송신자와 수신자 간에 연결을 설정하는 3-way handshake 과정을 거친 후 이를 통해 양쪽이 서로 연결되었음을 확인하고, 데이터 전송을 준비합니다.
    • 3-way handshake 과정:
      1. SYN: 클라이언트가 서버에게 연결 요청을 보냄.
      2. SYN-ACK: 서버가 요청을 수락하고 응답.
      3. ACK: 클라이언트가 서버의 응답을 확인하고 연결이 성립됨.
  1. 흐름 제어 (Flow Control)
  • TCP는 수신자의 버퍼가 넘치지 않도록 흐름 제어 기능을 지원합니다. 송신자는 수신자의 처리 속도를 고려하여 데이터를 전송하므로, 네트워크 혼잡을 방지할 수 있습니다.
  1. 혼잡 제어 (Congestion Control)
  • 네트워크 혼잡이 발생하지 않도록 TCP는 전송 속도를 조절합니다. 네트워크 상황에 따라 전송 속도를 동적으로 조정하여 데이터 전송의 효율성을 극대화합니다.

정도로 정리할 수 있다.

TCP 통신에서 buffer 사용 이유

  1. 바이너리 데이터 처리:
    • TCP 통신에서 전송되는 데이터는 바이너리 형태(이진데이터)로 전송됩니다. JavaScript의 기본 데이터 타입인 string이나 number는 바이너리 데이터로 바로 변환할 수 없으므로, 이를 처리하기 위해 Buffer 객체를 사용해야 합니다. 버퍼는 바이너리 형태를 효율적으로 다룰 수 있도록 설계된 객체입니다.

? 바이너리 형태란 ?

  • 바이너리 형태(Binary Form): 데이터를 2진수(0과 1)로 표현한 것.
    • 즉 버퍼를 사용하는 이유는 컴퓨터가 읽을 수 있도록 데이터를 이진 형태로 변경해주기 위해서 이다.

TCP 통신 사용 코드 분석

  1. net 모듈을 통해 TCP 서버 생성 (server측)
import net from 'net' 

const server = net.createServer((socket) => {
  
}
  • net 모듈이란?
    • net 모듈은 Node.js에서 TCP 서버나 클라이언트를 쉽게 생성하고 관리할 수 있도록 제공되는 기본 모듈. 이 모듈은 저수준의 네트워킹 작업을 자동으로 처리해 주기 때문에, 개발자는 복잡한 TCP 연결 설정 과정을 신경 쓰지 않고도 간단히 TCP 통신을 구현할 수 있다.

    • net.createServer()를 호출하면, TCP 서버가 생성되어 특정 포트에서 클라이언트의 연결 요청을 기다리게 됩니다.
    • TCP 연결이 설정되면, 서버는 연결된 클라이언트를 나타내는 소켓 객체(socket)를 생성 한 후 이 소켓 객체는 연결된 클라이언트와의 통신을 담당합니다.
  1. 클라이언트 접속 후 buffer 에 정보를 담아 서버에 전송
client.connect(PORT, HOST, () => {
  console.log('Connected to the server...');
  const message = 'Hello';
  const buffer = Buffer.from(message);

  const header = writeHeader(buffer.length, 11);
  const packet = Buffer.concat([header, buffer]); 
  // concat 헤더와 버퍼를 붙여서 하나의 배열로 만들어줌

  client.write(packet);
});
  • client가 connect를 통해 연결.
  • message라는 변수에 문자열 'Hello'를 담아
    buffer라는 변수에 Buffer.from( )을 통해 message를 Buffer 형태로 포장 한 후 header라는 변수를 writeHeader함수에게 전달한다.
  • 그리고 client.write를 통하여 서버로 다시 전송한다.

writeHeader함수를 알아보자


export const TOTAL_LENGTH_SIZE = 4;
export const HANDLER_ID = 2;
// 이 윗부분은 다른 코드에 있는 것을 보여주기 위해 들고온 것 export 신경 X

export const writeHeader = (length, handlerId) => {
  const headerSize = TOTAL_LENGTH_SIZE + HANDLER_ID; // 6
  const buffer = Buffer.alloc(headerSize);
  buffer.writeUInt32BE(length + headerSize, 0);
  buffer.writeUInt16BE(handlerId, TOTAL_LENGTH_SIZE);
  return buffer;
};
  • writeHeader 함수는 length와 handlerId를 매개 변수로 받아 실행된다.
  • 그러므로 length에는 message의 버퍼 길이, handlerId는 11이 현재는 들어 와 있다.
  • headerSize는 우리가 전달하고자 하는 데이터의 헤더부분을 설정하기 위해서 작성한 것이다 6바이트를 의미하게 된다.
  • buffer = Buffer.alloc(headerSize)에서 alloc( )은 괄호 안에 있는 크기 만큼 새로운 버퍼를 생성한다는 의미이다.
    • 즉, buffer라는 변수에 6바이트라는 새로운 버퍼를 생성한다.
  • 그 이후 writeUInt32BE와 writeUInt16BE를 통해 새롭게 생성된 buffer에 값을 저장시킨다.
    • writeUInt32BE와 writeUInt16BE란?
      빅인디안 형태를 의미하고 32BE는 32비트를 의미한다.
      8비트가 1바이트가 되므로 즉 4바이트를 의미하고
      버퍼의 첫 번째 4바이트에 전체 패킷의 길이(length + headerSize) 를 저장한다는 의미이고 0은 저장할 첫 시작점(여기서는 버퍼의 첫바이 트)을 의미한다.
    • 그렇다면 wirteUInt16BE는 2바이트에 handlerId라는 값을 저장하고 저장을 시작하는 지점은 TOTAL_LENGTH_SIZE 뒤 부터 저장한다!.
  1. 클라이언트에게 받은 정보로 서버에서 출력
socket.on('data', (data) => {
    // data가 buffer 객체로 들어오게됨
    const buffer = Buffer.from(data);
    const { length, handlerId } = readHeader(buffer);
    console.log(`handlerId: ${handlerId}`);
    console.log(`length: ${length}`);

    const handler = handlers[handlerId];

    const headerSize = TOTAL_LENGTH_SIZE + HANDLER_ID;
    const message = buffer.slice(headerSize);

    console.log(`client에게 받은 메세지: ${message}`);

    const responseMessage = handler(message);
    const responseBuffer = Buffer.from(responseMessage);

    const header = writeHeader(responseBuffer.length, handlerId);
    const packet = Buffer.concat([header, responseBuffer]);

    socket.write(packet);
  });
  • 이렇게 클라이언트가 전달한 정보는 data로 전달되고 이미 버퍼 형태로 전달되었지만 안정성을 위해 다시 한번 버퍼 형태로 저장해준다.
  • 그리고 현재 저 data안에는 불필요한 header에 관한 정보들이 포함되어 있기에 그 부분을 slice를 통해 제거 한 후 메세지로 출력해준다!

정리 끝

profile
Node.js_6기

0개의 댓글