TCP에 대한 이해
TCP/IP 프로토콜 스택
TCP/IP 프로토콜 스택이란
TCP/IP 프로토콜 스택은 네트워크에서 데이터를 어떻게 전송할지 정의하는 일련의 프로토콜입니다.
이 프로토콜들은 계층적 구조로 배치되며, 각 계층은 특정한 역할을 담당합니다. 이 계층적 구조는 일반적으로 네 가지 계층으로 나눠집니다. 4가지 영역은 물리 영역, 네트워크 영역, 트랜스포트 영역, 그리고 애플리케이션 영역으로 이루어져 있습니다.
LINK 계층
링크 계층은 네트워크 연결과 데이터 전송을 관리합니다. 예를 들어, 데이터를 작은 조각들로 나누고, 각 조각에 컴퓨터의 주소(MAC 주소)를 붙여 네트워크를 통해 전송하는 역할을 합니다. 또한, 전송 중 오류가 발생하면 해당 데이터를 다시 보내는 역할도 합니다.
IP 계층
IP 계층은 데이터를 올바른 목적지로 보내는 역할을 합니다. 이곳에서는 각 장치의 IP 주소를 사용하여 데이터 패킷이 올바른 방향(경로)으로 가게 되고, 여러 네트워크를 건너갈 수 있도록 도와줍니다.
해당 계층에서 사용되는 프로토콜을 IP라고 하는데 IP 자체는 비연결 지향적이고 신뢰할 수 없는 프로토콜인 것을 알고 있어야 한다.
따라서 데이터를 보낼 때마다 가는 경로를 선택하게 되고 그 경로는 일정하지 않게 됩니다.
또한 전송 도중 문제가 생겼다면 다른 경로를 선택해서 돌아가게 됩니다.
TCP/UDP 계층
TCP
TCP는 연결 지향적이며 신뢰성 있는 데이터 전송을 제공합니다. 이는 데이터의 순서를 보장하고, 패킷의 손실, 중복 또는 오류 없이 데이터를 전송합니다.
위 이미지처럼 A에서 B에 패킷 하나를 전송을 했을 때 B가 A에게 응답용 패킷을 전송을 한다.
그러면 수신을 했다는 의미이고 만약에 B가 A에게 응답용 패킷을 전송하지 않았다면 A는 B가 데이터를 수신하지 못한 것으로 간주하고 임의의 시간이 지난 다음 다시 전송을 하게 된다. 이를 이유로 IP가 데이터 전송을 보장하지 못하더라도 TCP로 인해 데이터 순서를 보장하게 되는 것이다.
더 자세한 TCP 구조에 대해서는 뒤에서 설명할 예정
Application 계층
Application 계층은 사용자가 네트워크 서비스에 직접 접근할 수 있게 해주는 계층입니다. 이 계층은 우리가 일상적으로 사용하는 웹 브라우저, 이메일 클라이언트, 메신저와 같은 응용 프로그램이 동작하는 영역입니다.
Application 계층에서는 프로토콜들이 동작하며, 이 프로토콜들은 사용자가 원활하게 서비스를 이용할 수 있도록 정보를 주고받는 규약을 정의합니다. 대표적인 Application 계층의 프로토콜로는 HTTP(Hypertext Transfer Protocol), FTP(File Transfer Protocol), SMTP(Simple Mail Transfer Protocol), DNS(Domain Name System) 등이 있습니다.
예를 들어, 웹 브라우저는 HTTP 프로토콜을 이용하여 서버와 통신하고 웹 페이지를 사용자에게 제공하며, 이메일 클라이언트는 SMTP 프로토콜을 이용하여 이메일을 전송합니다.
윈도우즈 기반 TCP 서버 구현
서버의 기본적인 함수 호출 순서
기본적으로 윈도우즈 기반 서버 구현을 위한 함수 호출순서는 위와 같다.
(거의 모든 TCP 기반의 서버 프로그램이 위와 같은 순서로 구현이 된다고 함)
이전 포스팅에서 위 순서에서 중 WSAStartup, socket, bind는 설명했으니 listen 함수부터 설명하겠습니다.
listen() 함수
listen 함수는 연결 요청 대기 상태로 들어가도록 해주는 함수이다.
int WSAAPI listen(
[in] SOCKET s,
[in] int backlog
);
- s : 이 매개변수는 listen() 함수가 작동하도록 설정할 소켓의 핸들을 나타냅니다. 이 소켓은 이미 socket() 함수를 사용하여 생성되었고, bind() 함수를 사용하여 특정 주소(서버의 IP 주소와 포트 번호)에 연결되어야 합니다. 이렇게 설정하면 이 소켓은 이제 클라이언트의 연결 요청을 수신할 준비가 된 것입니다.
- backlog : 이 매개변수는 연결 대기열(연결 요청 대기 큐)의 최대 길이를 설정합니다. 즉, 동시에 대기할 수 있는 클라이언트 연결 요청의 최대 수를 나타냅니다. 이 매개변수가 너무 작으면, 동시에 많은 연결 요청이 들어오는 상황에서 일부 연결 요청이 거부될 수 있습니다. 반면, 이 값이 너무 크면 불필요한 리소스를 사용하게 될 수 있습니다.
연결 요청 대기 : 여기서 연결 요청 대기 상태가 의미하는 뜻은 클라이언트가 연결 요청을 했을 때 연결이 수락될 때까지 연결 요청을 대기할 수 있다는 의미이다.
연결 요청 대기 큐 : 연결 요청 대기 큐의 의미는 말 그대로 대기열이라고 생각하면 된다
만약 A라는 사람이 어떠한 음식점에 입장하려고 하는데 입장 안내원이 현재 바빠서 번호표 뽑고 대기실로 안내를 해줬다 이를 연결 요청 대기 큐라고 생각하면 된다.
accept() 함수
accept() 함수는 대기 큐에 있는 연결 요청을 순서대로 수락하는 개념이다.
SOCKET WSAAPI accept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] int *addrlen
);
- s : 이 매개변수는 listen() 함수를 호출하여 클라이언트의 연결 요청을 수신하도록 설정된 소켓의 핸들을 나타냅니다. 즉, 클라이언트의 연결 요청을 수락하려는 서버의 소켓입니다.
- addr : 이 매개변수는 sockaddr 구조체의 포인터로, 연결을 요청한 클라이언트의 주소 정보(IP 주소와 포트 번호 등)를 저장합니다. 함수가 호출된 후에는 이 구조체에 클라이언트의 주소 정보가 저장됩니다.
- addrlen : 이 매개변수는 addr 매개변수로 제공된 구조체의 크기(바이트 단위)를 나타내는 포인터입니다. 함수가 호출되기 전에는 addr 매개변수로 제공된 구조체의 크기를 가리키고, 함수가 반환된 후에는 클라이언트의 실제 주소 크기를 가리킵니다.
윈도우즈 기반 TCP 클라이언트 구현
클라이언트의 함수 호출 순서는 서버보다 간단하다
bind, listen, accept가 없고 바로 connet 하여 서버에 연결을 요청하게 된다.
이전 서버에서 연결 요청 대기상태라는 것을 설명하였는데 이때 연결 요청이라는 부분이 connect에 해당하는 부분이다.
즉 클라이언트가 연결 요청하기 전에 서버에서 미리 연결 요청 대기상태가 된 이후 클라에서 연결을 요청해야 한다는 의미이다.
int WSAAPI connect(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen
);
- s : 이 매개변수는 연결을 시도할 소켓의 핸들입니다. 이 소켓은 이미 socket() 함수를 사용하여 생성되었어야 합니다.
- name : 이 매개변수는 클라이언트가 연결하려는 서버의 주소 정보를 가지고 있는 sockaddr 구조체를 가리킵니다. 이 구조체에는 서버의 IP 주소와 포트 번호가 포함됩니다.
- namelen : 이 매개변수는 name 매개변수로 제공된 sockaddr 구조체의 크기를 바이트 단위로 나타냅니다.
connect함수라 리턴되는 시점은 연결 요청이 서버에 의해 수락되거나 오류가 발생해서 중단되는 경우이다.
결국 connect() 함수는 클라이언트가 서버에 연결을 시도하고, 성공적으로 연결되면 해당 소켓을 통해 데이터를 전송하고 수신하는 데 사용됩니다.
TCP 서버/클라이언트 함수 호출 관계
위의 이미지는 서버 클라이언트 간 함수 호출 관계를 표현하는 이미지입니다.
여기서 중요한 부분은 클라이언트의 연결 요청은 서버가 연결 요청 대기 상태에 있을 때 진행되어야 하기 때문에
listen함수 호출 이후 connect함수를 호출해야 되는 부분이다.
또한 accept함수를 호출했을 때 연결 요청 대기 큐가 비어있다면 서버는 accept 함수 호출과 동시에 블로킹 상태가 되고
클라이언트의 연결 요청이 들어오면 연결 요청을 수락하면서 블로킹 상태에서 빠져나오게 된다.
해당 게시글은 서적을 통한 개인 공부 목적으로 작성된 글입니다.
출처 : TCP/IP 소켓 프로그래밍 서적
'TCP_IP 소켓 프로그래밍' 카테고리의 다른 글
UDP 기반 서버/클라이언트 (0) | 2023.06.16 |
---|---|
TCP 기반 서버 / 클라이언트에 대한 이해2 (에코 서버, TCP 내부 구조) (0) | 2023.06.14 |
IP 주소 체계와 데이터 정렬의 이해 (0) | 2023.06.12 |
소켓 프로그래밍에서 프로토콜이란 (1) | 2023.06.09 |
윈도우즈 기반 소켓 프로그래밍 이해하기 (0) | 2023.06.08 |
댓글