※ 본 카테고리의 내용은 부스트캠프 챌린지 기간동안 학습한 내용을 바탕으로 정리한 내용입니다.

 

목차


    0. 통신..?

     

     

    이전 포스팅에서 TCP와 UDP의 차이에 대해서 간략하게 알아보았습니다.

     

    그렇다면 자바스크립트를 이용해서 서버를 개설하고, TCP와 UDP 방식으로 실제로 무언가를 요청하고 받고 답해주는 무언가를 만들 수 있을 것이라고 쉽게 생각할 수 있습니다.

     

    원래 자바스크립트는 백엔드 서버를 만들기 위해 만들어진 언어는 아닙니다만, 어떻게든 자바스크립트로 서버를 구축하려는 노력을 바탕으로 자바스크립트 엔진인 크롬 V8에 비동기 이벤트 처리 라이브러리인 libuv를 결합하여 만들어낸 결과물이 바로 node.js입니다.

     

    이 node.js을 이용하면 http/https와 net(TCP)/dgram(UDP) 방식으로 서버를 만들거나, 클라이언트 환경에서 다른 서버에 접속할 수 있습니다.

    http/https를 이용하면 net/dgram방식보다 훨씬 간편하게 만들 수 있지만, low level에서 서버를 관리하는 방법을 알아보기 위해 본 포스팅에서는 net/dgram방식을 이용하여 서버를 개설하고 통신하는 방법에 대해서 알아보도록 하겠습니다.

     


    1. Net

    Net 방식TCP 프로토콜을 이용해서 원시데이터를 전송하는 방식입니다.

    server / client 형태로 존재하고 1:1로 연결하여 요청과 응답을 하게 됩니다.

    이 말은 서버와 클라이언트는 유일한 IP 주소와 포트 조합을 가져야 한다는 말이 되겠죠?!

     

    1.0. Net 예제 코드

    아래 코드는 서버와 클라이언트를 만드는 코드입니다.

    가장 핵심적인 부분만으로 구성된 코드인데요,

    각각의 코드에 대해서는 주석을 통해 어떤 기능을 하는지 추가해 놓았습니다.

     

    먼저 서버에서는 createServer를 이용해서 서버를 생성했고, 클라이언트로부터 데이터가 도착했을 때 출력하도록 만들었습니다.

    중간의 write 명령어를 통해 클라이언트에게 접속했을 때 환영한다는 메시지를 남겨주었고,

    마지막에 listen명령어를 통해 서버를 작동시켯을 때 5000번 포트로 메시지를 받는다는 말을 콘솔에 띄우도록 만들었습니다. 

     

    // tcpserver.js
    
    import net from "net";
    
    // net을 이용한 서버 생성
    const server = net.createServer(socket => { 
      console.log(socket.address().address + " connected.");
    
        // "data" : client로 부터 오는 data를 화면에 출력
        socket.on("data", function(data){
            console.log("data : " + data);
        });
    
        // "close" : client와 접속이 끊기는 메시지 출력
        socket.on("close", function(){
            console.log("client disconnected.");
        });
    
        // client가 접속하면 화면에 출력해주는 메시지 
        socket.write("welcome to server!!");
    });
    
    // 에러가 발생하면 처리
    server.on("error", err => {
      console.log(`error : ${err}`);
    });
    
    // 비동기적으로 5000번 포트를 통해 들어오는 메시지 수신 대기
    server.listen(5000, function() {
      console.log("listening on 5000");
    });

     

    클라이언트에서는 connect로 특정 서버에 접속할 수 있도록 했습니다.

    그리고 연결이 되었다면 서버에 연결되었다는 말을 남기고, 서버쪽에 i번 메시지 받아라~라고 전달되도록 만들었습니다.

     

    만약 서버로부터 데이터가 온다면 server.on("data"~) 에서 받을 수 있도록 했고, 접속이 종료되면 종료되었다는 메시지를 남기도록 했습니다.

    에러가 발생했을 때, timeout이 발생했을 때의 처리도 각각 해 주었습니다.

     

    // tcpclient.js
    
    import net from "net"; 
    
    // 5000번 포트로 서버에 접속
    const socket = net.connect({port : 5000});
    
    // "connect" : 연결이 되었을 때 동작
    socket.on("connect", function(){
        console.log("connected to server!"); 
        let i = 0;
    
        // setInterval을 이용해서 1초마다 메시지 전송(write 명령어)
        setInterval(function(){
            socket.write(`${i}번 메시지 받아라~`);
            i++;
        }, 1000);
    });
    
    // "data" : 서버로부터 받은 데이터를 화면에 출력
    socket.on("data", function(chunk){
        console.log("server : " + chunk);
    });
    
    // "end" : 접속이 종료됬을때 메시지 출력
    socket.on("end", function(){
        console.log("disconnected.");
    });
    
    // 에러가 발생할때 에러메시지를 화면에 출력
    socket.on("error", function(err){
        console.log(`error : ${err}`);
    });
    
    // connection에서 timeout이 발생하면 메시지 출력
    socket.on("timeout", function(){
        console.log("connection timeout.");
    });

     

    아래 사진은 서버를 켜고 클라이언트에서 메시지를 보냈을 때의 동작입니다.

     

     

    아래 메시지는 서버가 종료되었을 때 클라이언트에서의 에러처리입니다.

     

     

    아래 공식 문서를 통해 더 다양한 기능을 확인하실 수 있습니다!

     

    - 16.6.2 공식 영문 문서

     

    Net | Node.js v16.6.2 Documentation

    Net# Source Code: lib/net.js The net module provides an asynchronous network API for creating stream-based TCP or IPC servers (net.createServer()) and clients (net.createConnection()). It can be accessed using: const net = require('net'); IPC support# The

    nodejs.org

     

    - 0.10.7 한글 문서

     

    net Node.js v0.10.7 Manual & Documentation

    net# Stability: 3 - Stable The net module provides you with an asynchronous network wrapper. It contains methods for creating both servers and clients (called streams). You can include this module with require('net'); Stability: 3 - Stable net 모듈은

    nodejs.sideeffect.kr


    2. Dgram

    Dgram 방식UDP 프로토콜을 이용해서 원시데이터를 전송하는 방식입니다.

    Net 방식과 거의 동일합니다만 몇 가지 다른 부분이 있어서 추가로 주석에 달아놓았습니다.

     

    대표적으로 데이터를 전송할 때 write 대신 send를 사용한다는 점, 데이터를 수신할 때 data 대신 message를 사용한다는 점, 그리고 udp4 방식으로 서버를 연다는 차이점이 존재합니다.

     

    2.0. Dgram 예제 코드

    dgram 방식에서는 서버에서 메시지를 받았을 때 클라이언트의 주소를 받아서 클라이언트의 주소를 추가로 출력하도록 만들었고, 메시지를 수신대기할 때 전체 주소를 출력하도록 만들었습니다.

     

    // udpserver.js
    
    import dgram from "dgram";
    const server = dgram.createSocket('udp4');
    
    //에러 발생 시
    server.on('error', (err) => {
      console.log(`server error:\n${err.stack}`);
      server.close();
    });
    
    //클라이언트로부터 메시지 수신 시 작동
    server.on('message', (msg, remote_info) => {
      console.log(`server got: ${msg} from ${remote_info.address}:${remote_info.port}`);
    });
    
    // 비동기적으로 5000번 포트를 통해 들어오는 메시지 수신 대기
    server.on('listening', () => {
      const address = server.address();
      console.log(`server listening ${address.address}:${address.port}`);
    });
    
    // 5000번 포트와 "0.0.0.0" 기본 주소를 현재 서버와 바인딩
    server.bind(5000);

     

    클라이언트에서는 send를 통해 메시지를 전달하며, message로 메시지를 전달받습니다.

    그 외 나머지 부분은 동일합니다.

     

    // udpclient.js
    
    import dgram from "dgram";
    const socket = dgram.createSocket('udp4');
    
    // 5000번 포트로 연결
    socket.connect(5000);
    
    // "connect" : 연결이 되었을 때 동작
    socket.on("connect", function(){
        console.log("connected to server!"); 
        let i = 0;
    
        // setInterval을 이용해서 1초마다 메시지 전송(send 명령어)
        setInterval(function(){
            socket.send(`${i}번 메시지 받아라~`);
            i++;
        }, 1000);
    });
    
    // "message" : 서버로부터 받은 데이터를 화면에 출력
    socket.on("message", function(chunk){
        console.log("server : " + chunk);
    });
    
    // "end" : 접속이 종료됬을때 메시지 출력
    socket.on("end", function(){
        console.log("disconnected.");
    });
    
    // 에러가 발생할때 에러메시지를 화면에 출력
    socket.on("error", function(err){
        console.log(`error : ${err}`);
    });
    
    // connection에서 timeout이 발생하면 메시지 출력
    socket.on("timeout", function(){
        console.log("connection timeout.");
    });

     

    서버를 켜고 메시지를 받으면 아래와 같이 동작하게 됩니다.

    대신 이번에는 서버를 닫아도 클라이언트에서 에러를 발생하지 않습니다.

    반대로 클라이언트를 닫아도 서버에서 에러가 발생하지 않습니다.

     

    이것은 UDP 특성상 연결 자체가 없기 때문입니다. (따라서 1:1이 아닌 1:N, N:M 방식으로 연결될 수 있습니다)

    소켓이라는 이름을 사용해서 만들었지만, 실제로 소켓 대신 IP 기반으로 데이터를 전송합니다.

    그러므로 connect를 사용해서 연결을 하지 않고 특정 ip로 바로 send하더라도 정상적으로 데이터가 전송됩니다.

    따라서 훨씬 빠르고, 각 패킷은 독립적인 관계를 지니지만 신뢰성은 다소 떨어지는 편입니다.

     

     

    - v16.6.2 공식 영문 문서

     

    UDP/datagram sockets | Node.js v16.6.2 Documentation

    UDP/datagram sockets# Source Code: lib/dgram.js The dgram module provides an implementation of UDP datagram sockets. import dgram from 'dgram'; const server = dgram.createSocket('udp4'); server.on('error', (err) => { console.log(`server error:\n${err.stack

    nodejs.org

     

    - v0.10.25 한글 문서

     

    UDP / Datagram Sockets Node.js v0.10.25 Manual & Documentation

    UDP / Datagram Sockets# Stability: 3 - Stable Datagram sockets are available through require('dgram'). Important note: the behavior of dgram.Socket#bind() has changed in v0.10 and is always asynchronous now. If you have code that looks like this: var s = d

    nodejs.sideeffect.kr


     

    반응형
    • 네이버 블로그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기