TCP (Transmission Control Protocol) 헤더는 TCP 세그먼트의 시작 부분에 위치하여, 세그먼트가 정확하게 전송되고 수신되도록 제어하는 데 필요한 정보를 포함합니다. TCP 헤더는 최소 20 바이트이며, 다양한 필드를 통해 통신 세션을 관리합니다. TCP 헤더의 구조와 각 필드의 역할을 설명하겠습니다.
TCP 헤더 구조
TCP 헤더는 다음과 같은 필드들로 구성되어 있습니다
- 출발 포트 (Source Port): 송신 호스트의 포트 번호를 나타냅니다 (16비트).
- 목적지 포트 (Destination Port): 수신 호스트의 포트 번호를 나타냅니다 (16비트).
- 시퀀스 번호 (Sequence Number): 세그먼트의 첫 번째 바이트의 시퀀스 번호를 나타냅니다 (32비트). 연결 설정 시에는 초기 시퀀스 번호(ISN)로 사용됩니다.
- 확인 응답 번호 (Acknowledgment Number): 수신 측이 다음으로 기대하는 바이트의 시퀀스 번호를 나타냅니다 (32비트). ACK 플래그가 설정된 경우에만 유효합니다.
- 데이터 오프셋 (Data Offset): TCP 헤더의 길이를 32비트 워드 단위로 나타냅니다. 최소 값은 5 (20바이트)이며, 옵션 필드가 포함될 경우 더 길어집니다 (4비트).
- 예약됨 (Reserved): 미래 사용을 위해 예약된 필드입니다. 항상 0으로 설정됩니다 (4비트).
- 플래그 (Flags): 제어 비트로, TCP 세그먼트의 상태 및 제어 정보를 나타냅니다 (9비트). 주요 플래그는 다음과 같습니다:
- URG: 긴급 포인터 필드가 유효함을 나타냅니다.
- ACK: 확인 응답 번호 필드가 유효함을 나타냅니다.
- PSH: 수신 측에 데이터를 즉시 상위 계층으로 전달할 것을 요청합니다.
- RST: 연결을 재설정합니다.
- SYN: 연결 설정을 시작합니다.
- FIN: 연결을 종료합니다.
- 윈도우 크기 (Window Size): 송신 측이 수신할 수 있는 데이터의 최대 크기를 나타냅니다 (16비트).
- 체크섬 (Checksum): 헤더와 데이터의 무결성을 검사하는 값입니다 (16비트).
- 긴급 포인터 (Urgent Pointer): 긴급 데이터의 끝을 나타냅니다. URG 플래그가 설정된 경우에만 유효합니다 (16비트).
- 옵션 (Options): 다양한 TCP 옵션을 포함할 수 있으며, 가변 길이입니다. 주로 연결 설정 시 사용됩니다 (가변 길이).
- 패딩 (Padding): 헤더의 길이를 32비트 단위로 맞추기 위해 사용됩니다.
TCP 헤더의 예
필드 | 설명 | 길이 |
출발 포트 | 송신 호스트의 포트 번호 | 16비트 |
목적지 포트 | 수신 호스트의 포트 번호 | 16비트 |
시퀀스 번호 | 세그먼트의 첫 번째 바이트 시퀀스 번호 | 32비트 |
확인 응답 번호 | 다음으로 기대하는 바이트 시퀀스 번호 | 32비트 |
데이터 오프셋 | TCP 헤더 길이 (32비트 워드 단위) | 4비트 |
예약됨 | 미래 사용을 위한 필드 (항상 0으로 설정됨) | 4비트 |
플래그 | 제어 비트 (URG, ACK, PSH, RST, SYN, FIN) | 9비트 |
윈도우 크기 | 수신 가능한 데이터의 최대 크기 | 16비트 |
체크섬 | 헤더와 데이터의 무결성 검사 | 16비트 |
긴급 포인터 | 긴급 데이터의 끝 | 16비트 |
옵션 (옵션+패딩 포함) | 다양한 TCP 옵션 및 패딩 | 가변 길이 |
TCP 헤더를 사용하는 이유
TCP 헤더는 송신 및 수신 측에서 데이터 전송을 효과적으로 관리하고 오류를 감지하며, 데이터의 신뢰성을 보장하는 데 중요한 역할을 합니다. 각 필드는 TCP 연결의 특정 측면을 제어하고 모니터링하는 데 사용되며, 이를 통해 다음과 같은 기능을 수행할 수 있습니다:
- 연결 설정 및 해제: SYN, ACK, FIN 플래그를 사용하여 연결을 설정하고 해제합니다.
- 데이터 전송: 시퀀스 번호와 확인 응답 번호를 통해 데이터가 올바른 순서로 도착했는지 확인합니다.
- 흐름 제어: 윈도우 크기 필드를 사용하여 송신 측이 보낼 수 있는 데이터 양을 조절합니다.
- 오류 검출: 체크섬 필드를 통해 데이터의 무결성을 검증합니다.
이와 같이 TCP 헤더는 안정적이고 신뢰할 수 있는 데이터 전송을 위해 중요한 역할을 합니다.
TCP JAVA 사용 예시
Java를 사용하여 TCP 통신을 구현하고 TCP 헤더 정보를 표시하는 예제를 보여드리겠습니다. 이 예제는 기본적인 서버와 클라이언트를 포함하며, 클라이언트가 서버에 메시지를 보내고 서버가 이를 수신하여 TCP 헤더 정보를 표시합니다. 이 예제에서는 Java의 Socket과 ServerSocket 클래스를 사용합니다.
TCP 서버 (TCPServer.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) {
int port = 12345;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server started and listening on port " + port);
while (true) {
try (Socket clientSocket = serverSocket.accept()) {
System.out.println("Connection established with client");
// Print TCP header information
System.out.println("Local Port: " + clientSocket.getLocalPort());
System.out.println("Remote Port: " + clientSocket.getPort());
System.out.println("Local Address: " + clientSocket.getLocalAddress());
System.out.println("Remote Address: " + clientSocket.getInetAddress());
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println("Received: " + line);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
cs |
TCP 클라이언트 (TCPClient.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) {
String serverAddress = "127.0.0.1"; // Localhost
int port = 12345;
try (Socket socket = new Socket(serverAddress, port)) {
System.out.println("Connected to server");
// Print TCP header information
System.out.println("Local Port: " + socket.getLocalPort());
System.out.println("Remote Port: " + socket.getPort());
System.out.println("Local Address: " + socket.getLocalAddress());
System.out.println("Remote Address: " + socket.getInetAddress());
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
out.println("Hello, Server!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
cs |
동작 설명
- TCP 서버:
- 서버는 지정된 포트(12345)에서 클라이언트 연결을 대기합니다.
- 클라이언트가 연결되면, 서버는 연결된 소켓의 TCP 헤더 정보를 출력합니다.
- 서버는 클라이언트로부터 메시지를 수신하고 이를 출력합니다.
- TCP 클라이언트:
- 클라이언트는 지정된 서버 주소와 포트(127.0.0.1:12345)에 연결을 시도합니다.
- 연결이 성공하면, 클라이언트는 연결된 소켓의 TCP 헤더 정보를 출력합니다.
- 클라이언트는 서버로 "Hello, Server!" 메시지를 전송합니다.
이 예제에서는 소켓을 통해 TCP 통신을 수행하고, 소켓의 기본 정보를 통해 TCP 헤더 관련 정보를 출력합니다. 실제 TCP 헤더의 모든 세부 사항을 직접 볼 수는 없지만, 소켓의 포트 번호와 IP 주소 등의 정보를 확인할 수 있습니다. TCP 헤더의 세부 사항을 더 깊이 이해하려면 네트워크 패킷 분석 도구인 Wireshark 등을 사용하는 것이 좋습니다.