안녕하세요. 강창민 튜터입니다!
오늘 챌린지반 실질적인 첫 수업인데요! 오늘은 게임 서버 개발자 로드맵을 같이 구경하면서 여러분들이 어떤 역량을 갖추면 좋을지에 대해서 좀 살펴보도록 하겠습니다!
사실, 이번 수업 발표자료는 최소화하고 라이브로 얘기만 하려고 했으나 여러분들 까먹지말라고 발표자료를 준비했으니 로드맵 내용이 가물가물할 때쯤엔 다시 한 번 봐주세요!
Server Side Game Developer Roadmap
스탠다드반 수업을 들으면서 느끼시겠지만 TCP는 게임 개발에 있어서 아주 중요한 프로토콜입니다. 여기서 주요 부분에 대해서만 아주 짤막하게 얘기를 할게요!
Checksum (체크섬) - ★★★★☆
체크섬은 데이터 무결성을 확인하는 방법입니다!
게임에서 데이터가 손상되지 않고 전송되었는지 확인하는 데 중요합니다.
많이 쓰이는 패키지는 이런게 있어요.
예시 서버 코드
const net = require('net');
const crc = require('crc');
function calculateChecksum(data) {
// 페이로드를 16진수 기반의 문자열로 변환해요.
// 근데, 문자열의 길이가 8자리 미만이라면 앞쪽에 '0'을 추가하여 8자리를 맞춰요!
return crc.crc32(data).toString(16).padStart(8, '0');
}
const server = net.createServer((socket) => {
console.log('클라이언트 연결 감지!');
let buffer = Buffer.alloc(0);
socket.on('data', (data) => {
buffer = Buffer.concat([buffer, data]);
// 데이터가 충분히 도착했는지 확인
// (최소 9바이트: 1바이트 길이 + 8바이트 체크섬)
while (buffer.length >= 9) {
const length = buffer.readUInt8(0);
if (buffer.length < length + 9) break; // 완전한 메시지가 아직 도착하지 않음
// 패킷에서 페이로드와 체크섬 분해!
const payload = buffer.subarray(1, length + 1);
const receivedChecksum = buffer.subarray(length + 1, length + 9).toString();
const calculatedChecksum = calculateChecksum(payload);
if (receivedChecksum === calculatedChecksum) {
console.log('체크섬 일치! 데이터 유효성 확인!');
console.log('페이로드:', payload.toString());
// 여기서 페이로드 처리 로직을 구현하면 됩니다.
} else {
console.log('체크섬 불일치! 데이터 손상 확인!');
// 오류 처리 로직은 여기다 추가해주세요.
}
// 처리된 데이터를 버퍼에서 제거
buffer = buffer.subarray(length + 9);
}
});
socket.on('end', () => {
console.log('클라이언트 연결 종료');
});
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`서버가 ${PORT}번 포트에서 실행 중입니다.`);
});
예시 클라이언트 코드
const net = require('net');
const crc = require('crc');
function calculateChecksum(data) {
return crc.crc32(data).toString(16).padStart(8, '0');
}
const client = new net.Socket();
client.connect(3000, '127.0.0.1', () => {
console.log('서버에 연결 완료!');
const sendMessage = (message) => {
const payload = Buffer.from(message);
const length = Buffer.alloc(1);
length.writeUInt8(payload.length);
const checksum = Buffer.from(calculateChecksum(payload));
const packet = Buffer.concat([length, payload, checksum]);
client.write(packet);
};
sendMessage('안녕? 난 강창민이라고 해!');
setTimeout(() => sendMessage('너는 누구니?'), 1000);
setTimeout(() => client.end(), 2000);
});
client.on('close', () => {
console.log('연결 종료');
});
Segment Structure (세그먼트 구조) - ★★★★☆
Max Segment Size (최대 세그먼트 크기. 줄여서 MSS라고도 함) - ★★☆☆☆