거의 일주일을 집중하지 못했다..다시 하나하나 잡으면서 복습해야겠다..ㅠㅠ 화이팅!
소켓을 알기 전에 알아야할 지식은 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>
'포스코x코딩온 KDT 8기 풀스택 과정 회고록' 카테고리의 다른 글
[포스코 코딩온 KDT 8기] 웹 풀스택 과정 66일(09.18)차 회고 | React-JSX (0) | 2023.10.01 |
---|---|
[포스코 코딩온 KDT 8기] 웹 풀스택 과정 2차 프로젝트 | 서버 배포 >> 메인페이지 개발 시작 (0) | 2023.09.02 |
[포스코 코딩온 KDT 8기] 웹 풀스택 과정 45일(08.24)차 회고 | Sequelize 복습 (0) | 2023.08.25 |
[포스코 코딩온 KDT 8기] 웹 풀스택 과정 39일(08.17)차 회고 | JWT (0) | 2023.08.17 |
[포스코 코딩온 KDT 8기] 웹 풀스택 과정 38일(08.16)차 회고 | nginx로 서버배포 (0) | 2023.08.16 |