거의 일주일을 집중하지 못했다..다시 하나하나 잡으면서 복습해야겠다..ㅠㅠ 화이팅!


소켓을 알기 전에 알아야할 지식은 TCP/IP이다. 

 

TCP/IP는 컴퓨터 네트워크에서 데이터 통신을 위한 프로토콜 스택으로,

네트워크 간의 데이터 교환을 가능하게 하는 중요한 기술

• 데이터를 분할하여 보냄. • 정확한 전송을 보장하며 데이터의 경로를 지정하는 역할.

 

TCP

데이터를 신뢰성 있게 전송하기 위한 프로토콜이다.

대표적으로 4가지의 특징이 있다

신뢰성 : 데이터의 손실이나 손상을 최소화하고 데이터의 순서를 보장한다.

연결 지향 : 데이터를 주고받기 전에 송신자와 수신자 간의 연결

흐름 제어 : 데이터의 흐름을 제어하여 수신자가 처리할 수 있는 속도에 맞춰 데이터를 전송

혼잡 제어 : 네트워크의 혼잡 상태를 감지하고조절하여 네트워크 성능을 유지

 

IP

인터넷 상에서 데이터를 주고받기 위한 통신 규약

특징

패킷 기반 : 데이터를 작은 패킷 단위로 나누어 전송하고, 각 패킷은 목적지 주소와 출발지 주소 정보를 포함

비연결성 : 패킷은 독립적으로 처리되며, 수신자와의 직접적인 연결이 필요하지 않음

라우팅 : 각 라우터가 패킥의 경로를 결정하여 목적지까지 전달

IP주소 : IP는 각 컴퓨터를 식ㅂㄹ하기 위한 IP 주소를 사용

 

- 네트워크 인터페이스 계층 : 물리계층과 링크계층/ MAC 주소를 관리/ 이더넷이나 와이파이 같은 기술

- 인터넷 계층 : OSI 7계층의 네트워크 계층/ 주소 지정을 담당한다. / IP

- 전송 계층 : TCP, UDP 데이터의 신뢰성과 흐름을 제어

- 응용 계층 : 세션, 표현, 응용 계층/ 최종 사용자에게 서비스 제공하기 위한 응용프로그램과 사용자 인터페이스

 

UDP

신뢰성은 낮지만 속도가 빠름

데이터그램 단위로 데이터를 전송 > 순서와 데이터의 신뢰성이 보장되지 않음

제어 메커니즘이 없기에 오버헤드가 적음

방송이나 온라인 게임에서 많이 사용함

 


소켓

프로세스가 네트워크로 데이터를 내보내거나 데이터를 받기 위한 실제적인 창구 역할을 하는 것

- 서버와 클라이언트를 연결해주는 도구로써 인터페이스 역할을 한다.

- 소켓은 프로토콜, IP 주소, 포트 넘버로 정의된다.

- TCP와 UDP 프로토콜을 사용항 데이터를 전송

소켓 프로그래밍

- 서버 소켓 : 연결 요청을 받아 들임/ 클라이언트의 요청을 받고 통신을 위한 소켓을 생성

- 클라이언트 소켓 : 서버에 연결 요청/ 연결 수락 후 서버와 데이터 주고 받음

- 포트 : 컴퓨터 내에서 소프트웨어 간 통신을 할 때 사용되는 식별자

 

소켓 프로그래밍의 흐름


WebSocket

양방향 소통을 위한 프로토콜(약속)

• HTML5 웹 표준 기술

• 빠르게 작동하며 통신할 때 아주 적은 데이터를 이용

• 이벤트를 단순히 듣고, 보내는 것만 가능

• Handshake(핸드셰이크): 클라이언트가 서버로 웹소켓 연결을 요청할 때, 서버와 클 라이언트 간에 초기 핸드셰이크가 이루어며 이 핸드셰이크 과정을 통해 웹소켓 연결

• 클라이언트 측에서는 브라우저의 WebSocket 객체를 사용하여 웹소켓 연결을 생성하 고 관리

• 브라우저에서만 사용 가능

 

웹소켓 이벤트

- open : 웹소켓 연결이 성공적으로 열렸을 때  발생 

- message: 웹소켓을 통해 데이터를 주고받을 때 발생

- error: 웹소켓 연결 중 오류가 발생했을 때 발생. 연결 실패, 통신 오류 등이 해당

- close: 웹소켓 연결이 종료되었을 때 발생

 

백엔드에서 사용하기 위해선 별도의 라이브러리나 모듈이 필요하다.

 

백엔드에서 사용하기 위해선 ws를 설치해야한다.

npm i ws

ws 모듈 이벤트

• connection: 클라이언트가 웹소켓 서버에 연결되었을 때 발생.

이 이벤트 의 콜백 함수는 새로운 클라이언트 연결마다 실행

• message 이벤트: 클라이언트로부터 메시지를 받았을 때 발생

• error 이벤트: 웹소켓 연결 중 오류가 발생했을 때 발생

• close 이벤트: 클라이언트와의 연결이 종료되었을 때 발생

 

 

실습 >> 채팅창 만들기

bash 창 열어서 설치

npm init -y

npm i express ejs ws

app.js

const ws = require('ws');
const express = require('express')
const app = express();
const PORT = 8080;

app.set('view engine', 'ejs');

app.get("/", (req,res)=>{
    res.render('client');
});
 
const server = app.listen(PORT, ()=>{
    console.log('http://localhost:8080');
});


const wss = new ws.Server({server}); //서버 연결

//브라우저(클라이언트)들을 담을 변수 선언
const sockets = [];


//socket 변수는 접속한 브라우저
wss.on('connection', (socket) => {
    
    console.log("클라이언트와 연결 완료");// 주소 복사 후 탭을 한번 더 열면 소켓 하나가 더 생성되는 것이다.

    // sockets 변수에 브라우저 추가
    sockets.push(socket);


    socket.on("message", (message) => {//메세지가 생길떄마다
        console.log(`클라이언트로부터 받은 메세지: ${message}`);
        //클라이언트로 응답 메세지 전송
        // socket.send(`서버메세지: ${message}`);
        sockets.forEach((elem)=>{// 모든 브라우저에 있는 메세지를 반복문으로 전부 다 넣는다
            elem.send(`서버메세지: ${message}`);
        });
    });

    //오류
    socket.on("error", (err) => {
        console.log("에러 발생", err);
    });

    //접속 종료
    socket.on("close", () => {
        console.log("클라이언트와 연결 종료");
    });

});

client.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul></ul>
    <form id="chat">
        <input type="text" id="mess"/><br/>
        <button>채팅</button>
    </form>
    <script>
        const socket = new WebSocket("ws://localhost:8080");

        const chatF = document.querySelector("#chat");
        const ul = document.querySelector('ul');

        //서버에 연결
        socket.addEventListener("open", (event) => {
            // socket.send("헬러")
            console.log('서버에 연결되었다');
        });

        //메세지 주고 받음
        socket.addEventListener("message", (event) => {
            // console.log(event);
            // console.log(`서버로부터 박은 메세지: ${event.data}`);
            const li = document.createElement('li');
            li.textContent = event.data;
            ul.appendChild(li);
        });

        //오류 발생
        socket.addEventListener("error", (event) => {
            console.log('오류 발생', event.error);
        });

        //종료
        socket.addEventListener('close', (event) => {
            console.log("서버와 연결 종료")
        })


        ///////////////////////////////폼 이벤트//////////////////////////////
        chatF.addEventListener('submit', (event) => {
            event.preventDefault();//이벤트가 발생했을때 새로고침이나 창이동이 되지 않도록 막는것
            const msg = chatF.querySelector('#mess');
            socket.send(msg.value);
            
            // 객체로 보낼때 문자열로 바꾸어 주어야한다.
            socket.send(JSON.stringify({name: name.value, msg: msg.value}));
        })
    </script>
</body>
</html>

 

+ Recent posts