[Network] Socket 뜯어보기

은서·2026년 2월 4일

Network 네트워크

목록 보기
1/1
post-thumbnail

🔌 Socket이 무엇인지 알아보자

Socket과 TCP/UDP 소켓의 기본 구조를 알아봅니다.


1. Socket이란?

소켓(Socket)은 네트워크를 통한 입출력을 위해 사용자에게 필요한 수단을 제공하는 응용 프로토콜 인터페이스입니다.

인터페이스 == Socket

  • 인터페이스란 서로 다른 두 개의 시스템, 장치 사이에서 정보나 신호를 주고받는 경우의 접점이나 경계면을 의미합니다.
  • 네트워크에서의 인터페이스가 바로 Socket입니다.
  • OSI 모델에서 Transport Layer(4계층)Application Layer(5계층) 사이의 연결 역할을 합니다.
  • 소켓을 활용한 네트워크 응용 프로그램을 통해 네트워크상에서 데이터를 송/수신합니다.

네트워크 입/출력을 위한 5가지 요소

요소설명
프로토콜(Protocol)4계층에서 어떤 프로토콜을 사용하는지 (TCP/UDP)
소스 IP 주소데이터를 보내는 호스트의 IP
소스 포트 번호데이터를 보내는 프로세스 식별자
목적지 IP 주소데이터를 받는 호스트의 IP
목적지 포트 번호데이터를 받는 프로세스 식별자

💡 포트 번호는 네트워크에서 프로세스들의 식별자라고 생각하면 됩니다.


2. 포트(Port)

호스트 내에 실행되고 있는 프로세스(Process)를 구분 짓기 위한 16비트의 논리적 할당입니다.

  • 값의 범위: 0 ~ 65535
  • 통신의 주체는 프로세스와 프로세스 사이에서 이루어집니다.

포트 번호가 겹친다면?

  1. 나중에 실행한 프로세스가 죽을 수 있음
  2. 보통은 프로세스 둘 다 죽음

Well-Known Port

TCP 또는 UDP에서 IANA에 의해 할당된 0번 ~ 1023번까지의 포트입니다.

포트 번호서비스
20, 21FTP
22SSH
23Telnet
25SMTP
53DNS
80HTTP
443HTTPS

3. 데이터의 전송 순서 (Endian)

Big Endian vs Little Endian

방식설명
Big Endian상위 바이트의 값을 작은 번지수에 저장
Little Endian상위 바이트의 값을 큰 번지수에 저장

호스트 바이트 순서 vs 네트워크 바이트 순서

  • 호스트 바이트 순서: CPU별 데이터 저장 방식 (대부분 Little Endian - x86, AMD, Intel 계열)
  • 네트워크 바이트 순서: 통일된 데이터 송수신 기준 (Big Endian 사용)

⚠️ 네트워크 통신 시 바이트 순서 변환이 필요합니다!


4. 연결 지향형 소켓 (TCP 소켓, SOCK_STREAM)

SOCK_STREAM 소켓 특성

  • 스트림 방식의 소켓 생성 (UNIX 파이프 개념과 동일)
  • 메시지 경계가 유지되지 않음: 속도 조절, 네트워크 흐름 조절에 의해 서로 다른 메시지 크기를 가질 수 있음
  • 전달된 순서대로 수신됨 (순서 보장)
  • 전송된 모든 데이터는 에러 없이 도달 (신뢰성 보장)
  • 세부 기능 조절은 TCP(4계층)에서 이루어짐

💡 Socket의 역할: Application(5계층)에서 TCP로 보내달라고 Transport(4계층)에게 요청하기


5. TCP 소켓 프로그래밍 기본 구조

TCP Client가 n개 들어오면 Socket은 n+1개 존재합니다. (listen 소켓 1개 + 통신용 n개)

📌 TCP 통신 흐름

[Client]                              [Server]
   │                                     │
   │  socket() - 소켓 생성                 │  socket() - 소켓 생성
   │                                     │  bind() - IP/Port 바인딩
   │                                     │  listen() - 연결 대기
   │                                     │
   │ ─────── connect() ───────────────▶  │  accept() - 연결 수락
   │ ◀───── 3-way handshake ──────────▶  │  (새 소켓 생성)
   │                                     │
   │ ◀────── read/write ───────────────▶ │  (데이터 송수신)
   │                                     │
   │  close()                            │  close() (통신 소켓)
   │                                     │  close() (listen 소켓)

단계별 설명

1️⃣ Client 연결 준비 단계

  • socket(): 소켓 생성
  • address: 통신을 요청할 상대방(서버)의 주소 설정

2️⃣ Server 연결 준비 단계

  • socket(): 소켓 생성
  • address: 자신의 IP 주소와 Port 번호 설정 (누가 들어올지 모르니 내 정보만 설정)
  • bind(): IP와 Port 번호를 OS에게 알려주는 절차 ⭐ 매우 중요!
  • listen(): Client의 접속 요청을 대기하는 상태

3️⃣ 서비스 처리 단계

  • connect(): Client가 listen 중인 Server에게 연결 요청
  • accept(): Server가 새로운 소켓을 만들어 Client와 데이터 송수신 준비
  • read()/write(): 양측 모두 데이터 송수신
    • read == receive
    • write == send
  • close(): Client가 먼저 소켓 종료 → Server도 통신 소켓 종료

4️⃣ 서버 종료 단계

  • close(): listen 소켓까지 종료

3-Way Handshaking

TCP 연결 수립 과정 (connect ~ accept 구간)

Client                    Server
   │                         │
   │ ──── SYN ─────────────▶ │
   │ ◀─── SYN + ACK ──────── │
   │ ──── ACK ─────────────▶ │
   │                         │
   │     연결 수립 완료          │


6. Java TCP 소켓 예제

TCP Client

// 1. 사용자 입력을 위한 BufferedReader 생성
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));

// 2. 서버 연결 (hostname: 서버 IP, 6789: 포트 번호)
Socket clientSocket = new Socket("hostname", 6789);

// 3. 서버로 데이터 전송
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
String sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');

// 4. 서버로부터 응답 수신
BufferedReader inFromServer = new BufferedReader(
    new InputStreamReader(clientSocket.getInputStream()));
String modifiedSentence = inFromServer.readLine();

// 5. 소켓 종료
clientSocket.close();

TCP Server

// 1. ServerSocket 생성 및 바인딩 (포트 6789)
ServerSocket welcomeSocket = new ServerSocket(6789);

while (true) {
    // 2. 클라이언트 연결 대기 및 수락 (새 소켓 생성)
    Socket connectionSocket = welcomeSocket.accept();
    
    // 3. 클라이언트로부터 데이터 수신
    BufferedReader inFromClient = new BufferedReader(
        new InputStreamReader(connectionSocket.getInputStream()));
    String clientSentence = inFromClient.readLine();
    
    // 4. 대문자 변환 후 클라이언트에게 전송
    DataOutputStream outToClient = new DataOutputStream(
        connectionSocket.getOutputStream());
    String capitalizedSentence = clientSentence.toUpperCase() + '\n';
    outToClient.writeBytes(capitalizedSentence);
}

7. 비연결 지향형 소켓 (UDP 소켓, SOCK_DGRAM)

SOCK_DGRAM 소켓 특성

  • 데이터그램 방식의 소켓 생성
  • 개별적으로 주소가 쓰여진 패킷 단위 전송
  • 비연결형 서비스
특성설명
순서 보장 ❌패킷은 전달된 순서대로 수신되지 않음
신뢰성 ❌에러 복구를 하지 않음
크기 제한 ⭕데이터그램 패킷의 크기가 고정
Pipeline ❌TCP와 다르게 파이프라인 불가능

TCP vs UDP 비교

구분TCPUDP
연결연결 지향 (3-way handshake)비연결
신뢰성보장미보장
순서보장미보장
속도상대적으로 느림빠름
용도웹, 이메일, 파일 전송스트리밍, 게임, DNS

8. UDP 소켓 프로그래밍 기본 구조

[Client]                              [Server]
   │                                     │
   │  socket() - 소켓 생성                 │  socket() - 소켓 생성
   │                                     │  bind() - IP/Port 바인딩
   │                                     │
   │ ─────── sendto() ─────────────────▶ │  recvfrom()
   │ ◀────── recvfrom() ──────────────── │  sendto()
   │                                     │
   │  close()                            │  close()

💡 UDP는 connect(), accept()가 없습니다! 바로 데이터를 보내고 받습니다.


9. Java UDP 소켓 예제

UDP Client

// 1. DatagramSocket 생성
DatagramSocket clientSocket = new DatagramSocket();

// 2. 서버 주소 설정
InetAddress IPAddress = InetAddress.getByName("hostname");

// 3. 전송할 데이터 준비
byte[] sendData = new byte[1024];
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();

// 4. 패킷 생성 및 전송 (데이터, 길이, IP, 포트)
DatagramPacket sendPacket = new DatagramPacket(
    sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);

// 5. 응답 수신
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);

// 6. 소켓 종료
clientSocket.close();

UDP Server

// 1. DatagramSocket 생성 및 포트 바인딩
DatagramSocket serverSocket = new DatagramSocket(9876);

// 2. 수신 버퍼 준비 (경계 단위 고정)
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];

while (true) {
    // 3. 데이터 수신 대기
    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
    serverSocket.receive(receivePacket);  // 연결 없이 바로 receive
    
    String sentence = new String(receivePacket.getData());
    
    // 4. 클라이언트 정보 추출
    InetAddress IPAddress = receivePacket.getAddress();
    int port = receivePacket.getPort();
    
    // 5. 대문자 변환 후 응답 전송
    String capitalizedSentence = sentence.toUpperCase();
    sendData = capitalizedSentence.getBytes();
    
    DatagramPacket sendPacket = new DatagramPacket(
        sendData, sendData.length, IPAddress, port);
    serverSocket.send(sendPacket);
}

📚 핵심 정리

구분TCP (SOCK_STREAM)UDP (SOCK_DGRAM)
연결 방식연결 지향비연결
데이터 단위스트림 (경계 없음)데이터그램 (경계 있음)
순서 보장
신뢰성
서버 소켓 수n+1개 (Client n개 기준)1개
주요 메서드connect, accept, listensendto, recvfrom

🔗 참고

profile
개발자 대학생🌱

0개의 댓글