Socket(소켓)

Ga0·2023년 5월 7일
0

기타

목록 보기
2/14

소켓(Socket)

  • 네트워크를 경유하는 프로세스 간 통신의 종착점(응용계층)은 데이터 송수신을 위해 반드시 소켓을 거쳐 전송 계층으로 데이터를 전달해야 한다.
  • Client와 Server는 자신의 IP 주소와 소켓 연결에 할당할 Port 번호를 End Point로 삼고, IP주소와 Port 번호를 통해 소켓 연결을 기다리고, 수립하고, 통신하게 된다.

  • UDP는 비신뢰성(최소한의 오류 검사만 함) 전송 프로토콜이며, 비 연결형 서비스이다.

  • TCP는 신뢰성(오류 검사는 물론, 혼잡 제어, 흐름 제어도 수행) 있는 전송 프로토콜이며, 연결형 서비스이다.

  • 여기서 알 수 있는 것은 뭐든 검사가 많을 수록 속도가 느리다는 것이다. (즉 UDP가 속도가 더 빠르다.)
    -> 다시 주제로 넘어오면,

  • 소켓은 3가지 요소로 정의가 된다.

프로토콜

  • 메시지를 주고 받는 양식과 규칙의 체계(통신 규약 및 약속)

IP

  • 인터넷이 통하는 네트워크에서 어떤 정보를 수신하고 송신하는 통신에 대한 규약을 의미
  • Internet Protocol의 줄임말로 인터넷상에서 사용하는 주소체계를 의미

PORT

  • IP 내에서 애플리케이션 상호 구분(프로세스 구분)을 위해 사용하는 번호

HTTP 통신 방식

  • HTTP : Hyper Text Transfer Protocol의 약자로 HTML 파일을 전송하는 프로토콜이며, 웹 브라우저에서 통신이 일어난다. 이미지, HTML 파일, JSON 파일 등 전송

Socket 통신 방식

  • Socket : 두 프로그램이 서로 데이터를 주고 받을 수 있는 양 쪽에 생성되느 통신 단자로, 서버와 클라이언트 양방향 연결이 이러어지는 통신으로 클라이언트도 서버로 요청을 보낼 수 있고, 서버도 클라이언트로 요청을 보낼 수 있는 통신

동작 원리


1. Client가 서버에 요청(Request)을 보낸다.
2. 서버는 Socket 객체를 생성하고, Client에서 전송한 데이터(메시지)를 입력 스트림(파일 데이터를 읽거나 네트워크 소켓을 통해 데이터를 읽거나 키보드에서 입력한 데이터를 읽을 때 사용)을 통해 읽어온다.

webSocket.current = new WebSocket("ws://localhost:8080/소켓주소");

// 클라이언트 소켓이 서버 소켓에 접속했을 때 이벤트
webSocket.current.onopen = ()=>{
  console.log("웹 소켓 접속했습니다.");
}

package ezenweb.web.socket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

//* 소켓 매핑을 잡아줌
@Configuration // 컴포넌트 등록 [주요 : Service , Controllerm Repository 등등]
@Slf4j
@EnableWebSocket // * 웹 소켓 연결 WSA 프로토콜, WS 프로토콜의 URL 매핑 연결
public class WebSocketConfiguration implements WebSocketConfigurer { //implments : 구현 하다

    @Autowired //컴포넌트에 등록한 클래스 이므로 @Autowired 가능
    private  ChattingHandler chattingHandler; //의존성 주입(DI)

    @Override //서버 소켓으로 사용되고 있는 클래스를 등록(프론트 주소(라우터)와 겹치면 절대 안됨!!!!!)
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //chatHandler를 chat이라는 주소로 매핑하며, 들어올 수 있는 도메인은 모두("*")이다.
        registry.addHandler(chattingHandler, "/chat").setAllowedOrigins("*");
        //registry.addHandler(서버소켓 객체, "서버소켓의 path/url").setAllowedOrigins("*"); : 서버소켓 등록 함수
            //.setAllowedOrigins("접속허용 도메인") : 해당 서버소멧으로 부터 요청할 수 있는 URL/도메인
            //.setAllowedOrigins("*") : 해당 서버소멧으로 부터 요청할 수 있는 URL/도메인

        //서버 소켓이 더 있으면 의존성 주입 객체를 만들고 위처럼 해당 객체로 더 추가하면된다.

    }
}
//** 서버소켓에 접속한 명단 저장 WebSocketSession : 스프링꺼 사용
private static List<WebSocketSession> connectionList = new ArrayList<>(); //접속 명단
    
//클라이언트가 서버소켓으로 접속했을 때
@Override 
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
      log.info("afterConnectionEstablished : " + session);
      connectionList.add(session); //클라이언트 세션에 들어왔을 때 리스트에 추가[다른 세션들과 통신하기 위해]
}
  • 메시지가 처리와 관련된 예시 코드는 아래와 같다.
  1. 서버는 Client에서 전송한 데이터를 처리하고, 결과를 출력 스트림을 통해 클라이언트에 전송한다.
  2. Client는 서버에 전송한 데이터를 받아 화면에 출력한다.
webSocket.current.onmessage =  (e)=>{
  	console.log("웹 소켓 메시지왔습니다.");
  
 	let data = JSON.parse(e.data); //서버로부터 받은 메시지 형변환 JSON 형식으로 변환(웹에서 읽기 위해 => 화면에 출력하기 위해)
}
//클라이언트로 부터 메시지 받았을 때
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
      log.info("handleTextMessage : " + session);

      for(WebSocketSession conn : connectionList) {
          conn.sendMessage(message); //메시지 보냄
      }
   }
  1. Socket을 닫는다. (+에러 발생시 js)

//서버소켓 나갔을 때
webSocket.current.onclose = (e)=>{console.log("웹 소켓 나갑니다.");}

//서버소켓과 오류가 발생했을 때
webSocket.current.onerror = (e)=>{console.log("웹 소켓 에러 발생했습니다.");}
// 클라이언트가 서버 소켓으로 부터 나갔을 때
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
      log.info("afterConnectionClosed : " + session);
      connectionList.remove(session); //클라이언트 세션이 나갔을 때 리스트 제거
   }
}

0개의 댓글