# 오늘 한 내용 [접기/펼치기]
## 팀회의팀원 소개
팀장 정하기
지원자 등장!!
팀명 정하기
팀명 투표로 1론머스크 조
팀 규칙 정하기
팀 규칙은 1차 개인 과제 와 2차 팀과제로 나눠짐
팀 목표 정하기
팀 목표는 1차 개인 과제 와 2차 팀과제로 나눠짐
코딩 컨벤션 설정
정보 공유 추가
개인 트러블 슈팅 저장소 추가
정기회의 14:00
마지막 스몰토크 20:30
강의
TCP
서버
- TCP 에코 서버를 구현합니다. 클라이언트가 연결하면 데이터를 수신하고,
- 연결 종료 시 메시지를 출력하며, 오류를 처리합니다.
- 서버는 포트 5555에서 클라이언트의 연결을 기다립니다.
- 클라이언트가 데이터를 보내면 그 내용을 콘솔에 출력합니다.
모듈 임포트:
- `net` 모듈은 TCP 및 IPC(Inter-Process Communication) 소켓을 생성하고 관리하는 데 사용되는 Node.js의 내장 모듈입니다.
- `import net from 'net';`
포트 정의:
- `서버가 리스닝할 포트를 `5555`로 설정합니다.`
- `const PORT = 5555;`
서버 생성:
- `net.createServer()` 메서드를 호출하여 새로운 TCP 서버를 생성합니다.
- `socket` 매개변수는 클라이언트와의 연결을 나타내는 소켓 객체입니다.
- `const server = net.createServer((socket) => {`
클라이언트 연결 시 로깅:
- 클라이언트가 서버에 연결되면 해당 클라이언트의 IP 주소와 포트 번호를 출력합니다.
- ``console.log(`client connected from : ${socket.remoteAddress}:${socket.remotePort}`);``
데이터 수신 처리:
- 클라이언트로부터 데이터가 수신되면 `data` 이벤트가 발생하며, 수신된 데이터를 출력합니다.
- ``socket.on('data', (data) => { console.log(`received data from client : ${data}`); });``
클라이언트 연결 종료 시 로깅:
- 클라이언트가 연결을 종료하면 `end` 이벤트가 발생하며, 해당 클라이언트의 IP 주소와 포트 번호를 출력합니다.
- ``socket.on('end', () => { console.log(`client disconnected from : ${socket.remoteAddress}:${socket.remotePort}`); });``
오류 처리:
- 소켓에서 오류가 발생하면 `error` 이벤트가 발생하며, 오류 메시지를 출력합니다.
- ``socket.on('error', (error) => { console.error(`error : ${error}`); });``
서버 리스닝 시작:
- 서버가 지정된 포트에서 연결을 기다리기 시작합니다. 서버가 성공적으로 시작되면 서버의 IP 주소와 포트 번호를 출력합니다.
- ``server.listen(PORT, () => { console.log(`echo server is running on ${server.address().address}:${server.address().port}`); });``
클라이언트
- TCP 클라이언트를 구현하여 서버에 연결하고, 메시지를 전송하며,
- 서버로부터 응답을 수신하고 처리하는 기능을 갖추고 있습니다.
- 헤더를 작성하고 읽는 유틸리티 함수와 상수를 사용하여 메시지 패킷의 구조를 정의하고,
- 이를 통해 클라이언트와 서버 간의 통신을 원활하게 수행합니다.
모듈 임포트:
- `net`: TCP 소켓을 생성하고 관리하는 Node.js의 내장 모듈입니다.
- `writeHeader` 및 `readHeader`: 데이터 패킷의 헤더를 작성하고 읽는 유틸리티 함수입니다.
- `HANDLER_ID` 및 `TOTAL_LENGTH_SIZE`: 패킷의 헤더 크기와 관련된 상수입니다.
- `import net from 'net'; import { writeHeader, readHeader } from './utils.js'; import { HANDLER_ID, TOTAL_LENGTH_SIZE } from './constants.js';`
서버 연결 정보:
- 클라이언트가 연결할 서버의 호스트와 포트를 설정합니다. 여기서는 로컬호스트의 5555 포트를 사용합니다.
- `const HOST = 'localhost'; const PORT = 5555;`
클라이언트 소켓 생성:
- TCP 소켓을 생성합니다.
- `const client = new net.Socket();`
서버에 연결:
- `client.connect()` 메서드를 사용하여 서버에 연결합니다.
- 연결이 성공하면 "Connected to server" 메시지를 출력합니다.
- `client.connect(PORT, HOST, () => { console.log('Connected to server');`
메시지 전송:
- `"Hello"`라는 메시지를 `Buffer`로 변환하여 `test`에 저장합니다.
- `writeHeader(test.length, 11)`를 호출하여 메시지의 길이와 핸들러 ID를 포함하는 헤더를 작성합니다.
- `Buffer.concat([header, test])`를 사용하여 헤더와 메시지를 결합하여 하나의 패킷을 생성합니다.
- `client.write(packet)`를 통해 서버에 패킷을 전송합니다.
- `const message = 'Hello';
- `const longMessage = 'V'.repeat(1024);
- `const test = Buffer.from(message);
- `const header = writeHeader(test.length, 11);
- `const packet = Buffer.concat([header, test]);
- `client.write(packet);`
데이터 수신 처리:
- 서버로부터 데이터를 수신할 때 `data` 이벤트가 발생합니다.
- 수신된 데이터는 `Buffer`로 변환되고, `readHeader(buffer)`를 호출하여 핸들러 ID와 메시지 길이를 읽습니다.
- 헤더 크기를 계산하여 메시지 본체를 추출하고, 이를 출력합니다.
- ``client.on('data', (data) => { const buffer = Buffer.from(data); const { handlerId, length } = readHeader(buffer);
console.log(`handlerId: ${handlerId}`); console.log(`length: ${length}`); const headerSize = TOTAL_LENGTH_SIZE + HANDLER_ID; const message
= buffer.subarray(headerSize); console.log(`server from message: ${message}`); });``
연결 종료 처리:
- 서버와의 연결이 종료되면 `close` 이벤트가 발생하고, "Connection closed" 메시지를 출력합니다.
- `client.on('close', () => { console.log('Connection closed'); });`
오류 처리:
- 클라이언트에서 오류가 발생하면 `error` 이벤트가 발생하고, 오류 메시지를 출력합니다.
- `client.on('error', (err) => { console.error('Client error:', err); });`
상수정의
export const TOTAL_LENGTH_SIZE = 4;
export const HANDLER_ID = 2;
export const MAX_MESSGE_LENGTH = 1024;
헨들러
const handler10 = (data) => {
const processed = data.toString().toUpperCase();
return Buffer.from(processed);
};
export default handler10;
대문자 변환
const handler11 = (data) => {
const processed = data.toString().split('').reverse().join('');
return Buffer.from(processed);
};
export default handler11;
순서뒤집기
import handler10 from "./handler10.js";
import handler11 from "./handler11.js";
const hanlders = {
10: handler10,
11: handler11
}
export default hanlders;
해당 기능실행
통신테스트
유틸
이 코드는 주어진 바이너리 데이터에서 헤더 정보를 읽고,
지정된 정보를 바탕으로 새로운 헤더를 작성하는 기능을 제공합니다.
데이터 통신이나 파일 포맷 처리 등에서 유용하게 사용될 수 있습니다.
Import 문
import { TOTAL_LENGTH_SIZE, HANDLER_ID } from "./constants.js";
TOTAL_LENGTH_SIZE
와HANDLER_ID
는constants.js
파일에서 가져온 상수입니다.
readHeader
함수
export const readHeader = (buffer) => {
return {
length: buffer.readUInt32BE(0),
handlerId: buffer.readUInt16BE(TOTAL_LENGTH_SIZE),
};
};
입력: buffer
는 바이너리 데이터가 담긴 버퍼입니다.
기능:
- `buffer.readUInt32BE(0)`: 버퍼의 첫 번째 4바이트를 읽어 Big Endian 형식으로 `length`를 반환합니다.
- `buffer.readUInt16BE(TOTAL_LENGTH_SIZE)`: `TOTAL_LENGTH_SIZE` 위치에서 2바이트를 읽어 `handlerId`를 반환합니다.
출력: 객체 형태로 length
와 handlerId
를 반환합니다.
writeHeader
함수
export const writeHeader = (length, handlerId) => {
const headerSize = TOTAL_LENGTH_SIZE + HANDLER_ID;
const buffer = Buffer.alloc(headerSize);
buffer.writeUInt32BE(length + headerSize, 0);
buffer.writeUint16BE(handlerId, TOTAL_LENGTH_SIZE);
return buffer;
}
입력: length
와 handlerId
는 각각 헤더의 길이와 핸들러 ID입니다.
기능:
- `headerSize`는 헤더의 총 크기를 계산합니다.
- `Buffer.alloc(headerSize)`: 지정된 크기의 빈 버퍼를 생성합니다.
- `buffer.writeUInt32BE(length + headerSize, 0)`: 헤더의 길이를 포함한 값을 버퍼의 첫 번째 위치에 Big Endian 형식으로 씁니다.
- `buffer.writeUint16BE(handlerId, TOTAL_LENGTH_SIZE)`: `handlerId`를 `TOTAL_LENGTH_SIZE` 위치에 씁니다.
출력: 작성된 헤더를 담고 있는 버퍼를 반환합니다.
readUInt32BE(0)
버퍼의 첫 4바이트를 읽어서 정수로 변환 한다.
readUInit16BE(TOTAL_LENGTH_SIZE)
버퍼
'TIL' 카테고리의 다른 글
TIL_2025-01-07 (0) | 2025.01.07 |
---|---|
TIL_2025-01-06 (0) | 2025.01.06 |
TIL_2025-01-02 (0) | 2025.01.02 |
TIL_2024-12-31 (0) | 2024.12.31 |
TIL_2024-12-30 (0) | 2024.12.31 |
댓글