Three-way-HandShake 및 서버 구동

Soozoo·2024년 7월 1일

JAVA

목록 보기
34/41

Three-Way-HandShake

The Three-Way Handshake (또는 TCP Three-Way Handshake)는 TCP/IP 프로토콜을 사용하여 컴퓨터간에 연결을 설정할 때 사용되는 절차입니다.

1. 첫 번째 단계: 클라이언트가 서버에 연결 요청 (SYN)

  • 클라이언트서버에 TCP 연결을 요청합니다.
  • 클라이언트는 먼저 SYN (Synchronize Sequence Number) 패킷을 보냅니다.
  • 이 패킷에는 클라이언트의 초기 sequence number (시퀀스 번호)가 포함되어 있습니다.
  • 시퀀스 번호는 데이터 전송의 순서를 관리하기 위한 중요한 역할을 합니다.

2. 두 번째 단계: 서버가 클라이언트의 연결 요청을 수락 및 확인 (SYN-ACK)

  • 서버는 클라이언트의 SYN 패킷을 받으면, 이를 수락하고 클라이언트로부터의 연결을 요청합니다.
  • 서버는 SYN 패킷에 응답하여 SYN-ACK 패킷을 클라이언트에게 보냅니다.
  • SYN-ACK 패킷은 서버의 초기 sequence number와 함께 전송됩니다.
  • 서버는 이전에 받았던 클라이언트의 sequence number에 1을 더한 값을 자신의 acknowledgment number (승인 번호)로 설정하여 클라이언트에게 전송합니다.

3. 세 번째 단계: 클라이언트가 서버의 응답을 확인 (ACK)

  • 클라이언트는 서버로부터의 SYN-ACK 패킷을 받으면, 이에 대한 응답으로 ACK (Acknowledgment) 패킷을 보냅니다.
  • ACK 패킷에는 클라이언트가 서버의 sequence number를 받았다는 것을 알리는 acknowledgement number가 포함됩니다.
  • 이후부터는 클라이언트와 서버 간에 데이터 전송이 이루어집니다.

요약

  • Three-Way Handshake는 TCP/IP 프로토콜 스택에서 연결을 설정할 때 사용되며, 데이터 전송의 신뢰성과 정확성을 보장합니다.
  • 클라이언트서버SYN 패킷을 보내고, 서버가 이를 SYN-ACK 패킷으로 응답하고, 클라이언트가 이를 ACK 패킷으로 확인하는 과정을 포함합니다.
  • 각 패킷은 초기 sequence number와 acknowledgment number를 포함하여 데이터의 순서와 정확성을 보장합니다.

TCP 소켓 프로그래밍은 네트워크 프로그래밍의 기본입니다. 이번 포스트에서는 Java를 사용하여 간단한 TCP 서버와 클라이언트를 구현하는 방법을 알아보겠습니다. 이 예제를 통해 클라이언트가 서버에 메시지를 보내고, 서버가 해당 메시지에 응답하는 기본적인 채팅 애플리케이션을 만들 수 있습니다.

TCP 서버 구현

먼저, 서버 측 코드입니다. 서버는 특정 포트에서 클라이언트의 연결 요청을 기다리고, 연결이 이루어지면 클라이언트로부터 메시지를 수신하고 응답을 보냅니다.


package ex03.net.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTest {
    public static void main(String[] args) {
        ServerSocket ss = null;
        Socket s = null;
        System.out.println("Server Start~~~~~~~");

        try {
            ss = new ServerSocket(9000); // 9000번 포트에서 서버 소켓을 생성
            s = ss.accept(); // 클라이언트의 연결을 대기

            // 입력 및 출력 스트림 생성
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();

            byte[] arr = new byte[100];
            is.read(arr); // 클라이언트로부터 메시지 수신
            System.out.println(new String(arr));

            String message = "안녕....Client......";
            os.write(message.getBytes()); // 클라이언트로 응답 메시지 전송

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                s.close();
                ss.close();
            } catch (IOException e2) {
                e2.printStackTrace();
            }
        }
    }
}

서버 코드 설명

  1. 서버 소켓 생성: ServerSocket을 9000번 포트에 바인딩하여 생성합니다.
  2. 클라이언트 연결 수락: accept() 메서드를 호출하여 클라이언트의 연결 요청을 수락합니다.
  3. 입출력 스트림 설정: InputStreamOutputStream을 사용하여 클라이언트와의 데이터 통신을 처리합니다.
  4. 클라이언트 메시지 수신 및 응답: 클라이언트로부터 메시지를 읽어 콘솔에 출력하고, 응답 메시지를 클라이언트로 전송합니다.
  5. 자원 해제: 사용한 소켓과 서버 소켓을 닫습니다.

TCP 클라이언트 구현

이제, 클라이언트 측 코드입니다. 클라이언트는 서버에 연결을 요청하고, 서버로 메시지를 보내고 서버로부터 응답을 받습니다.


package ex03.net.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ClientTest {
    public static void main(String[] args) {
        Socket s = null;

        try {
            s = new Socket("192.168.0.143", 9000); // 서버 IP 및 포트로 소켓 생성

            // 입력 및 출력 스트림 생성
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();

            String str = "안녕하세요....Server~~~~~";
            os.write(str.getBytes()); // 서버로 메시지 전송

            byte[] buffer = new byte[100];
            is.read(buffer); // 서버로부터 응답 메시지 수신
            System.out.println(new String(buffer));

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                s.close();
            } catch(IOException e) {
                e.printStackTrace();
            }
        }
    }
}

클라이언트 코드 설명

  1. 서버에 연결: 지정된 서버 IP와 포트로 소켓을 생성하여 서버에 연결합니다.
  2. 입출력 스트림 설정: InputStreamOutputStream을 사용하여 서버와의 데이터 통신을 처리합니다.
  3. 서버로 메시지 전송 및 응답 수신: 서버로 메시지를 보내고, 서버로부터 응답 메시지를 받아 콘솔에 출력합니다.
  4. 자원 해제: 사용한 소켓을 닫습니다.

실행 방법

  1. 서버 실행: ServerTest 클래스를 먼저 실행하여 서버를 시작합니다. "Server Start~~~" 메시지가 콘솔에 출력되면 서버가 정상적으로 실행된 것입니다.
  2. 클라이언트 실행: ClientTest 클래스를 실행하여 클라이언트가 서버에 연결하고 메시지를 전송합니다. 클라이언트와 서버 간의 메시지 주고받기를 콘솔에서 확인할 수 있습니다.

실행 결과

  1. 서버 실행:

2.클라이언트 실행:

3.서버에서 클라이언트 메세지 확인:

profile
넙-죽

0개의 댓글