소켓

황희윤·2023년 11월 28일

소켓 (Socket)

TCP나 UDP와 같은 전송 계층(Transport layer)을 추상화해 개발자가 프로그래밍을 쉽게 할 수 있도록 한다.

  • 데이터 송수신에 대한 하드웨어와 소프트웨어적인 사항에 신경 쓰지 않게 해준다.

  • 자바에서는 java.net 패키지를 사용해 소켓을 제공한다.

TCP 프로토콜

  • 연결 지향(Stream 기반 소켓)

    • 데이터 송신측과 수신측에서 전용의 데이터 전용 선로(session)을 만든다.
    • 데이터의 신뢰도가 중요할 때 사용한다.
  • 1:1 통신으로 한 포트에 하나의 서버 소켓만 연결 가능

  • 자체적으로 오류를 처리

  • 네트워크 전송 중 순서가 뒤바뀐 메시지를 재조합한다.

자바의 TCP 클래스

Socket 클래스

  • 클라이언트와 서버 모두에 사용하는 클래스
  • 프로세스 간의 통신을 담당
  • 입력 Stream과 출력 Stream을 가지고 있다.

ServerSocket 클래스

  • 서버에 사용하는 클래스
  • 포트와 연결(bind)되어 외부의 요청을 기다린다.
  • 연결 요청이 오면 소켓을 새로 생성해준다.

TCP 통신 절차

  1. 대기 : 서버는 클라이언트보다 먼저 실행되어서 서버 소켓을 사용해서 서버 컴퓨터의 특정 포트에서 클라이언트의 연결 요청을 처리할 준비를 한다.

  2. 클라이언트 연결 요청 : 클라이언트는 연결할 서버의 IP 주소포트 번호로 소켓을 생성해서 서버에 연결(connect)을 요청한다.

  3. 서버 요청 수락 : 클라이언트의 요청을 받으면 서버에 새로운 소켓을 생성해서 클라이언트의 소켓과 연결되도록 한다(accept). 이제 1:1 통신이 가능해졌다.

  4. 서버의 데이터 처리 : 클라이언트가 보낸 데이터를 받아서(receive) 처리한다.

  5. 서버의 데이터 전송 : 클라이언트에게로 데이터를 보낸다.

  6. 클라이언트의 데이터 처리 : 클라이언트는 서버로부터 받은 데이터를 처리한다.

TCP 서버에서 사용한 메서드 순서

  • socket() ➡️ bind() ➡️ listen() ➡️ accept() ➡️ read() & write() ➡️ close()

TCP 클라이언트에서 사용한 메서드 순서

  • socket() ➡️ connect() ➡️ read() & write() ➡️ close()

UDP 프로토콜

  • 비연결 지향

    • 단순히 데이터를 전송하거나 받기만 하는 프로토콜이다.
    • 연결 설정이 없다.
    • IP 주소만으로 데이터를 전송한다.
  • 오류를 처리하지 않는다.

  • 신뢰할 수 없다.

  • 메시지 순서를 재조합해 주지도 않는다.

  • 실시간으로 데이터를 주고 받을 때 사용한다.

  • 신뢰성보다는 빠른 통신을 추구

  • UDP를 사용하는 대표적인 애플리케이션은 DNS(Domain Name System)다.

  • TCP의 오버헤드를 피하고자 BroadcastMulticast를 사용할 때 UDP를 사용한다.

  • TCP와 다르게 데이터를 패킷(packet)으로 나누고, 수신측에서 재조립하는 과정을 거치지 않는다.

  • 패킷(packet) : 데이터 전송에서 사용하는 데이터의 묶음

  • 데이터 크기는 64kb로 제한된다.

  • 자바에서는 DatagramSocket 클래스와 DatagramPacket 클래스, MulticastSocket 클래스가 있다.

자바 UDP 클래스

DatagramSocket

  • UDP 패킷을 송수신하는 기능을 제공

  • 비연결형 프로토콜인 UDP의 특성에 따라 3way-handshaking 등의 설정 절차 없이 DatagramPacket을 상대에게 전달하는 기능을 제공

  • 서버 소켓과 소켓의 구분이 없어서 DatagramSocket이 두 가지 역할을 한다.

DatagramPacket

  • UDP 데이터 구성을 위한 데이터그램 패킷을 추상화한 클래스

UDP 통신 절차

  1. 데이터를 바이트 단위로 분할DatagramPacket 객체로 포장한다. DatagramPacket 객체에 전송할 곳의 주소와 포트 번호를 적는다.
String sendStr = "Hello Java!";
byte[] by = sendStr.getBytes();
  1. DatagramPacket 객체로 데이터(패킷)를 만들어 전송한다. 소켓은 특별한 포트 번호를 가지지 않아도 된다.
DatagramSocket ds = new DatagramSocket();
ds.send(dp);
ds.close();
  1. 데이터를 전송받는 곳을 만들어 준다. 데이터를 전송할 위치(포트), 전송받은 데이터를 보관하는 공간을 만들어야 한다. 먼저 전송받을 공간을 DatagramPacket 객체로 확보하고 다음으로 소켓을 통해 전송받으면 된다.
byte[] btData = new byte[65508];
DatagramPocket dp = new DatagramPacket(byData, byData.length); 
DatagramSocket.ds = new DatagramSocket(15554);
ds.receive(dp);
ds.close();
  1. DatagramPacket 객체 내에 저장된 내용(보낸 곳의 주소, 포트 번호, 전송받은 내용 등)을 분석하고 출력한다(get).
InetAddress addr = dp.getAddress();
int pot = dp.getPort();
int length = dp.getPort();
byte[] data = dp.getData();

UDP 통신 요약

수신측

  1. DatagramSocket 생성 - 포트번호를 가지고 생성
  2. DatagramPacket 생성 - 바이트 배열과 크기만을 가지고 생성
  3. receive() 메서드를 호출해서 데이터를 전송받고 해석

송신측

  1. DatagramSocket 생성 - 기본 생성자를 이용해서 생성(매개 변수 없음)
  2. DatagramPacket 생성 - 기록된 바이트 배열과 크기, 전송할 곳의 IP, 포트 번호를 가지고 생성
  3. 소켓이 send() 메서드를 호출해서 데이터 전송
profile
HeeYun's programming study

0개의 댓글