[Java] Server-Client 직렬화/역직렬화

Jeini·2025년 9월 29일
0

☕️  Java

목록 보기
69/70
post-thumbnail

❗️ 소켓 프로그래밍에 대한 기본 개념을 익히고, 데이터 직렬화/역직렬화 대해 알아보자


📡 정보 전달과 Server-Client 구조


📌 서버(Server)

서버는 정보(데이터)나 서비스를 제공하는 쪽

  • 쉽게 말하면, 요청받으면 응답해주는 컴퓨터/프로그램이라고 생각하면 된다.
  • 예를 들어, 유튜브에서 영상을 보려고 할 때, 유튜브 서버가 동영상 데이터를 보내준다.

👉 특징

  • 항상 켜져 있어야 함 (요청이 언제 들어올지 모르니까)
  • 데이터를 보관하고 관리함 (DB 연결 등)
  • 서비스 제공자의 역할 (예: 로그인, 게시판, 파일 다운로드)

📌 클라이언트(Client)

클라이언트는 정보를 요청하는 쪽

  • 쉽게 말하면, 서버에 “이거 줘!” 하고 요청하는 사용자 컴퓨터/앱/브라우저라고 보면 된다.
  • 예를 들어, 네가 크롬 브라우저로 네이버를 접속하면, 크롬(=클라이언트)이 네이버 서버에 “홈페이지 보여줘!”라고 요청하는 것.

👉 특징

  • 요청(Request)을 보냄
  • 응답(Response)을 받아서 사용자에게 보여줌
  • 서버 없이는 혼자 할 수 있는 게 제한적임

📌 Server-Client 구조

대체로 하나의 Server와 다수의 Client로 이루어져 있다.

둘은 Request ↔ Response 방식으로 통신한다.

구조를 단순화하면 이렇게 된다👇

클라이언트(나, 사용자) → 요청(Request) → 서버
클라이언트(나, 사용자) ← 응답(Response) ← 서버

🔹 예시: 네이버 접속할 때
1. 브라우저(클라이언트): “네이버 메인 페이지 주세요!”
2. 네이버 서버: “여기 있습니다!” 하고 HTML, CSS, JS 파일 전달
3. 브라우저: 받아서 화면에 보여줌


🌐 네트워크(Network)

컴퓨터와 컴퓨터를 연결하는 통신망

  • 우리가 인터넷을 쓸 수 있는 이유는, 수많은 컴퓨터와 서버들이 네트워크로 연결되어 있기 때문이다.

👉 예시

  • 집에서 와이파이로 휴대폰이 인터넷에 연결되는 것도 네트워크
  • 회사에서 사내 서버(DB)에 접속하는 것도 네트워크
  • 즉, 정보가 오가는 길(도로, 통신망)이 네트워크이다 🚗

🔌 소켓(Socket)

네트워크에서 서버와 클라이언트가 실제로 대화(데이터 교환)할 수 있게 해주는 창구

  • 프로그래밍에서 서버-클라이언트가 통신하려면 소켓을 열어야 한다.

👉 특징

  • 소켓은 양쪽 끝이 있는 통신선 같은 것
  • 클라이언트와 서버는 각각 소켓을 만들어서 연결해야 통신할 수 있다.
  • TCP/UDP 같은 프로토콜을 기반으로 작동한다.

⚙️ 흐름 이해하기

  1. 서버: 소켓을 열고 기다림 (☎ 전화 받는 모드)
  2. 클라이언트: 서버 주소(IP, 포트 번호)로 연결 요청 (📞 전화를 검)
  3. 연결 성공하면: 서로 데이터를 주고받음 (대화 시작)
  4. 끝나면: 소켓을 닫음 (📴 전화 끊기)

🔌 소켓과 스트림 관계

소켓들이 연동되고 나면 데이터 전송을 위한 스트림을 생성 가능하다.

1. 소켓(Socket)은 연결통로

  • 소켓은 서버와 클라이언트가 서로 데이터를 주고받기 위해 만든 연결통로(파이프 같은 통로)다.
  • TCP 소켓을 연결하면, 양쪽이 “대화할 준비”가 된 상태이다.

2. 스트림(Stream)은 데이터 흐름통로

  • 스트림은 데이터가 한쪽에서 다른 쪽으로 흐르는 방식을 추상화한 개념이다.
  • 데이터를 한 줄기(stream)처럼 흘려보낸다 → 이게 스트림.
  • 소켓이 열리면 내부적으로 InputStream(받는 쪽)OutputStream(보내는 쪽)이 만들어진다.

👉 즉, 소켓 + 스트림 = 실제 데이터 송수신 가능

3. TCP 소켓에서 스트림

  • TCP 소켓은 양방향 통신을 지원한다.
  • 그래서 하나의 소켓 안에서:
    InputStream : 상대방이 보낸 데이터를 읽는 통로
    OutputStream : 내가 상대방한테 데이터를 보내는 통로

👉 프로그래밍적으로는 보통 이렇게 한다. 👇 (Java 예시)

Socket socket = new Socket("127.0.0.1", 8080);

// 보내는 스트림 (클라이언트 → 서버)
OutputStream out = socket.getOutputStream();
out.write("Hello Server".getBytes());

// 받는 스트림 (서버 → 클라이언트)
InputStream in = socket.getInputStream();
byte[] buffer = new byte[1024];
int len = in.read(buffer);
System.out.println("서버 응답: " + new String(buffer, 0, len));

socket.close();

4. 비유 🍔

  • 소켓 = 전화선 (서로 연결된 상태)
  • InputStream = 전화에서 내 귀로 들어오는 소리
  • OutputStream = 전화에서 내 입에서 나가는 소리
  • 전화선(소켓)이 연결되어야 서로 대화(스트림)할 수 있다!

📡 Java 소켓 프로그래밍

1️⃣ 서버 코드 (Server.java)

import java.io.*;
import java.net.*;

public class Server {
    public static void main(String[] args) {
        int port = 5000; // 서버 포트 번호
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("서버가 시작되었습니다. 포트: " + port);

            // 클라이언트 연결 대기
            Socket socket = serverSocket.accept();
            System.out.println("클라이언트 연결됨: " + socket.getInetAddress());

            // 데이터 송수신 스트림 생성
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

            // 클라이언트 메시지 받기
            String message = in.readLine();
            System.out.println("클라이언트로부터: " + message);

            // 서버 응답 보내기
            out.println("안녕 클라이언트! 나는 서버야 😎");

            // 소켓 닫기
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2️⃣ 클라이언트 코드 (Client.java)

import java.io.*;
import java.net.*;

public class Client {
    public static void main(String[] args) {
        String host = "127.0.0.1"; // 서버 주소 (로컬호스트)
        int port = 5000; // 서버 포트 번호

        try (Socket socket = new Socket(host, port)) {
            System.out.println("서버에 연결되었습니다.");

            // 데이터 송수신 스트림 생성
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

            // 서버에 메시지 보내기
            out.println("안녕 서버! 나는 클라이언트야 🖐️");

            // 서버 응답 받기
            String response = in.readLine();
            System.out.println("서버로부터: " + response);

            // 소켓 닫기 (try-with-resources가 자동 닫음)
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

⚙️ 실행 순서

  1. 먼저 Server 실행 → 포트 5000 에서 대기
  2. 그 다음 Client 실행 → 서버에 연결
  3. 서로 메시지 교환
[서버]
서버가 시작되었습니다. 포트: 5000
클라이언트 연결됨: /127.0.0.1
클라이언트로부터: 안녕 서버! 나는 클라이언트야 🖐️

[클라이언트]
서버에 연결되었습니다.
서버로부터: 안녕 클라이언트! 나는 서버야 😎

✅ 정리

  • 서버는 ServerSocket 으로 대기 → 클라이언트가 연결하면 Socket 생성.
  • 클라이언트는 바로 Socket 으로 서버에 연결 시도.
  • 연결되면 양쪽에서 InputStream / OutputStream 으로 메시지를 주고받음.
profile
Fill in my own colorful colors🎨

0개의 댓글