소켓 (Socket)은 소프트웨어로 작성된 추상적인 개념으로 네트워크 상 두 프로그램 간의 엔드포인트이다.
쉽게 말하면 네트워크 상에서 데이터를 주고 받는 창구 역할을 한다고 보면 되며, 소켓은 IP주소와 포트 번호의 조합으로 식별된다.
이미지 출처 - https://sparcs.org/blog/how-to-use-websocket/
HTTP는 이전 포스트를 통해 설명했기 때문에 간단히 설명하겠다.
HTTP는 Hypertext Transfer Protocol의 약자이며 웹에서 정보를 주고 받기 위한 프로토콜이다.
HTTP 통신은 기본적으로 요청 / 응답으로 이루어진다.
이미지 출처 - https://sparcs.org/blog/how-to-use-websocket/
Keep-Alive
헤더를 이용해 연결 유지 가능)HTTP Message에 관한 자세한 설명은 이전 포스트 참고
연결 방식:
통신 방향:
실시간성:
상태 유지:
리소스 사용:
사용 사례:
HTTP 통신은 웹 페이지 로딩과 RESTful API에 사용되며 리소스 사용이 효율적이라는 장점이 있다. 그러나 실시간 통신이나 반복적인 통신의 경우 비효율적인데 소켓 통신의 이점은 이 때 드러난다.
소켓 통신은 실시간 통신이 가능하고 무엇보다도 서버 -> 클라이언트 방향으로 먼저 정보를 전송하는게 가능하다.
따라서 소켓 통신은 실시간 채팅이나 온라인 게임등 실시간 정보 전달이 중요한 서비스에서 이용된다.
Echo 서버는 클라이언트로부터 받은 메시지를 그대로 다시 클라이언트에게 돌려주는 서버이다.
이런걸 학습하는게 무슨 의미가 있을까?
그 이유는 바로 Echo 서버는 소켓 통신의 기본을 이해하는데 매우 유용하다.
Echo 서버의 동작은 앞서 말했던 소켓 통신의 동작과 완벽히 똑같다.
Node.js는 비동기 이벤트 기반의 자바스크립트 런타임으로, 소켓 프로그래밍에 매우 적합합니다. Node.js의 net
모듈을 사용하여 Echo 서버를 구현해 보겠습니다.
const net = require('net');
const readline = require('readline');
// 소켓 생성.
const client = new net.Socket();
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// 2024는 서버가 리스팅하는 포트 번호
// 0,0,0,0는 모든 네이트워크 인터페이스 (로컬 호스트의 경우 "localhost" 또는 "127.0.0.1"을 사용.
client.connect(2024, '0.0.0.0', () => {
// readline을 이용해서 사용자 입력을 기다리기 위해 prompt사용.
rl.prompt();
});
// 서버에서 보낸 데이터를 받는 부분.
client.on('data', (data) => {
console.log(data.toString());
rl.prompt();
});
// 종료 시켰을 때 이벤트
client.on('close', () => {
console.log('서버와 연결 종료');
rl.close();
});
// 입력을 서버로 보내는 부분.
rl.on('line', (input) => {
// 0을 입력하면 접속 종료.
if (input === "0") client.destroy();
client.write(input);
});
rl.on('close', () => {
client.destroy();
});
const net = require('net');
class EchoServer {
constructor(port) {
this.port = port;
// 서버가 생성될 때마다 (socekt)=>{} 콜백 실행.
this.server = net.createServer((socket) => this.handleConnection(socket));
}
start() {
// 0,0,0,0 으로 설정해서 모든 네트워크 인터페이스에서 받는다.
this.server.listen(this.port, '0.0.0.0', () => {
// 서버가 시작할 때 사용 될 콜백
// 이부분에 콘솔을 출력하면 서버가 시작되면 콘솔을 출력한다.
});
}
handleConnection(socket) {
// ip 주소는 socket.remoteAddress
// 포트 번호는 socket.remotePort
// 연결을 활성상태로 유지
socket.setKeepAlive(true);
// 데이터를 즉시 전송
socket.setNoDelay(true);
// 클라이언트가 보낸 데이터 처리 부분.
socket.on('data', (data) => {
// data를 통해 서버에 정보가 온다.
// data.toString()을 통해 문자열로 바꿔서 출력하면 출력 된다.
const input = data.toString().trim();
// 이부분을 통해 다시 클라이언트에게 전달.
socket.write(input + "\n");
// 전달 후 종료.
socket.end();
});
socket.on('end', () => {
// 종료시 콜백 코드
});
socket.on('error', (err) => {
// 에러 발생시 콜백 코드
});
}
}
const server = new EchoServer(2024);
server.start();
서버 실행: 서버 코드를 실행하여 Echo 서버를 시작합니다.
node server.js
클라이언트 실행: 클라이언트 코드를 실행하여 서버에 연결하고 메시지를 전송합니다.
node client.js
TELNET을 이용해서
telnet [IP or Domain] [port]
명령을 터미널에 입력해서 실행시킬 수도 있다.
Socket 통신 & HTTP 통신
TCP 기반 서버 / 에코 서버
TELNET