inblog logo
|
sxias
    자바

    [JAVA] 69. 소켓 통신

    문정준's avatar
    문정준
    Feb 20, 2025
    [JAVA] 69. 소켓 통신
    Contents
    1. 통신을 하기 위해 필요한 것2. 소켓 통신3. 고정 IP / 내부 IP4. 단방향 통신5. 반이중 통신6. 전이중 통신
    ✅
    다른 디바이스와 통신을 하기 위해서 필요한 것
    1. 프로토콜
    1. IP 주소 (4바이트 : 42.9억개)
    1. 포트 번호 (2바이트 : 65000개)
    1. 소켓 + 버퍼(BR, BW)
     

    1. 통신을 하기 위해 필요한 것

    • 각 앱(프로그램)은 실행되면 프로세스로 전환
    • 프로세스들은 고유 번호인 PID (Process ID) 를 가짐
      • PID는 CPU가 관리
    • 외부에서 데이터가 필요한 (통신을 하는) 프로세스들은 포트 번호를 가짐
      • 포트 번호는 중복될 수 없음 (중복 시 데이터 충돌)
    • 통신을 하기 위해 필요한 것
        1. 프로토콜 : 통신 방법, 규약
        1. IP 주소 : 통신을 할 상대의 주소, 약 42.9억개
        1. 포트 번호 : 데이터를 받거나 보낼 프로세스의 번호, 약 65000개
        1. 소켓 : 데이터가 들어오고 나가는 공간
            • 버퍼를 활용 (BufferedWriter, BufferedReader)
    notion image
     

    2. 소켓 통신

    • 소켓을 통한 통신을 위해서는 3가지 정보로 소켓을 만들어야 함
      • 프로토콜 - TCP, UDP
      • IP 주소 : Client 측에서 Server에게 접속
      • 포트 번호 : 어떤 프로세스에 접근할 것인지 확인
    • 통신을 진행할 때 전송되는 데이터는 Header와 Body로 구분
      • Header : IP 주소, 포트 번호 등이 달려있는 세그먼트 ( Redundancy, Overhead )
      • Body : 본 내용 ( Plain Text or Payload )
    • 어플리케이션 층에서도 프로토콜이 필요
      • 가장 유명한 것이 HTTP 프로토콜 ( URL을 받아 서버에서 파일 전송 )
    • 기다리면 Server, 요청하면 Client
      • Client가 요청 > Server가 소켓 연결 후 데이터 전송 (응답) > Client가 응답
     
    notion image
    • 서버가 소켓을 Open하면, 소켓 내부의 Listener는 포트에 접속하는 다른 기기를 관찰
    • 포트로 접속한 것을 확인하면, 다른 기기와 소켓을 연결
      • 이때, 서버의 포트가 아닌 무작위의 포트를 선정하여 소켓을 연결함
      • 포트를 연결하는 동안 서버 소켓은 다시 요청이 들어오는 기기를 관찰
    • Client - Server 간 통신 방법
        1. 클라이언트 측의 데이터 요청 (BufferedReader를 이용한 키보드 입력)
        1. 서버 측의 BufferedReader를 통한 데이터 확인 후 파싱
            • 프로토콜에 따른 데이터 해석 및 응답 준비
        1. 서버 측의 BufferedWriter와 프로토콜을 통한 응답
        1. 클라이언트 측의 BufferedReader를 통한 응답 확인
    notion image
     

    3. 고정 IP / 내부 IP

    • 인터넷을 사용할 때, 인터넷의 종류에 따라 고정 IP / 유동 IP가 나뉨
    • 유동 IP의 경우 가상의 IP를 부여받고, 이는 실제 IP와는 차이가 있음
      • 공유기의 ‘192.168.0.1’ 주소가 보통 가상 IP 주소
    notion image
     

    4. 단방향 통신

    • Client - BufferedWriter
    package ex20.ch01; import java.io.*; import java.net.Socket; public class MyClient01 { public static void main(String[] args) { // 단방향 (One-way) 통신 : 클라이언트 // localhost : loopback address (내 주소) try { // 소켓 연결 Socket socket = new Socket("localhost", 20000); // 키보드 입력 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); System.out.println("키보드 입력 대기중.."); String msg = in.readLine(); // 전송 BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); out.write(msg); out.write("\n"); out.flush(); } catch (IOException e) { throw new RuntimeException(e); } } }
    • Server - BufferedReader
    package ex20.ch01; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class MyServer01 { public static void main(String[] args) { // 단방향 (One-way) 통신 : 서버 try { ServerSocket ss = new ServerSocket(20000); System.out.println("서버 소켓이 대기중입니다. 연결을 시도해주세요."); // 서버 소켓이 연결을 인지하면 새 소켓 생성 (포트는 무작위) Socket socket = ss.accept(); // 프로세스 멈춤 (대기 상태) System.out.println("소켓이 연결되었습니다."); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String body = ""; body = br.readLine(); System.out.println("서버측 : " + body); } catch (IOException e) { throw new RuntimeException(e); } } }
    ✅
    주의할 점
    1. 서버 측 코드를 우선 실행하고 클라이언트를 실행해야 통신이 정상적으로 작동
    1. localhost : loopback address
        • 나의 주소를 라우터에서 받아오는 게 아닌, 바로 자신을 가리키게 하는 키워드
    1. 항상 입출력은 App의 입장에서 생각하기
        • 들어오면 Input, 나가면 Output
        • Output 시 ‘\n’ 필수 포함! ( 없으면 null로 인식 )
    • Client
    notion image
    • Server
    notion image

    5. 반이중 통신

    • Half-duplex 방식, 데이터를 전송받고 그에 대한 응답을 다시 전송
    package ex20.ch02; import java.io.*; import java.net.Socket; public class MyClient02 { public static void main(String[] args) { // 반이중 (Half-duplex) 통신 : 클라이언트 // localhost : loopback address (내 주소) try { // 소켓 연결 Socket socket = new Socket("localhost", 20000); // 키보드 입력 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); System.out.println("키보드 입력 대기중.."); String reqbody = in.readLine(); // 전송 BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); out.write(reqbody); out.write("\n"); out.flush(); // 응답 확인 BufferedReader in2 = new BufferedReader(new InputStreamReader(socket.getInputStream())); String respbody = in2.readLine(); System.out.println(respbody); } catch (IOException e) { throw new RuntimeException(e); } } }
    package ex20.ch02; import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class MyServer02 { public static void main(String[] args) { // 반이중 (Half-duplex) 통신 : 서버 try { ServerSocket ss = new ServerSocket(20000); System.out.println("서버 소켓이 대기중입니다. 연결을 시도해주세요."); // 서버 소켓이 연결을 인지하면 새 소켓 생성 (포트는 무작위) Socket socket = ss.accept(); // 프로세스 멈춤 (대기 상태) System.out.println("소켓이 연결되었습니다."); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String reqbody = ""; reqbody = br.readLine(); System.out.println("서버측 : " + reqbody); // 전송 받은 후 응답 // 프로토콜 작성 ( name을 받으면 metacoding, age를 받으면 39 전송 ) String respbody = ""; if (reqbody.equals("name")) { respbody = "metacoding"; } else if (reqbody.equals("age")) { respbody = "39"; } else { respbody = "error"; } BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bw.write(respbody); bw.write("\n"); bw.flush(); } catch (IOException e) { throw new RuntimeException(e); } } }
    ✅
    반이중 통신 방식 구조
    1. 클라이언트 측의 데이터 요청 (BufferedReader를 이용한 키보드 입력)
    1. 서버 측의 BufferedReader를 통한 데이터 확인 후 파싱
        • 프로토콜에 따른 데이터 해석 및 응답 준비
    1. 서버 측의 BufferedWriter와 프로토콜을 통한 응답
    1. 클라이언트 측의 BufferedReader를 통한 응답 확인
    1. 1 ~ 4 반복 혹은 소켓 close (세션 종료)
    • Client
    notion image
    • Server
    notion image

    6. 전이중 통신

    • Full-duplex 방식, 동시에 데이터 요청, 응답이 이루어짐
    • 스레드(thread)를 활용
    notion image
     
     

    🚫 통신이 안되는 이유 : 방화벽 (Firewall)

    • 기본적으로 방화벽은 모든 포트를 차단 ( Negative Strategy )
    • 어플리케이션이 포트 통신을 요청하면 그 포트 번호를 허용 ( Inbound )
      • Inbound를 통해 내/외부 네트워크에 Access 가능한 서버를 DMZ라고 함
      • DMZ 개방 : 방화벽의 모든 포트를 개방하여 어디서든 DMZ 서버에 접근 가능한 상태
    notion image
     
    Share article
    Contents
    1. 통신을 하기 위해 필요한 것2. 소켓 통신3. 고정 IP / 내부 IP4. 단방향 통신5. 반이중 통신6. 전이중 통신

    Sxias ㆍ a32176740@gmail.com

    RSS·Powered by Inblog