본문 바로가기

네트워크 프로그래밍

TCP / IP 소켓 프로그래밍 -4-

TCP에 대한 이해

TCP(Transmission Control Protocol)는 전송과정을 컨트롤한다라는 뜻

 

TCP / IP 프로토콜 4단계 스택

 

1)물리적 계층 - LINK

가장 기본이 되는 영역으로 LAN,WAN, MAN 등 네트워크 표준과 관련된 프로토콜을 정의

 

2)네트워크 계층 - IP

복잡하게 연결되어 있는 인터넷을 통해 데이터를 보내기 위해 경로를 선택하는 것.

IP 자체는 비연결 지향적이며 신뢰할 수 없다. 데이터를 보낼 때 마다 경로를 선택하게 되고 그 경로도 일정하지 않기 때문이다.

 

3)전송 계층 - TCP /UDP

데이터를 전송하는 방법을 정의하는 영역.

IP를 기반으로 호스트 대 호스트가 어떻게 데이터를 주고 받을 것인지 약속하는 것을 담당하는 것이다.

TCP는 확인 절차를 걸쳐서 신뢰성 없는 IP를 기반으로 하여 신뢰성을 부여해주는 프로토콜이다.

 

4)어플리케이션 계층 - Application

 

TCP기반 서버 구현

 

기본적인 함수 호출 순서

socket()  ->        bind()          ->        listen()         ->   accept()     ->     read()&write()      -> close

소켓생성 ->   소켓에 주소할당   ->  연결요청대기상태  ->  연결허용     ->     데이터 송수신      -> 연결종료

 

int listen(int s, int backlog);

s       : 클라이언트의 연결 요청을 받아들이는 역할을 하게 될 소켓(서버소켓)의 파일 디스크립터를 인자로 전달

backlog : 연결요청대기 큐의 크기. 인자가 5이면 클라이언트의 연결 요청을 5개까지 대기시킬 수 있게 된다.

 

int accept(int s, struct sockaddr *addr, int *addrlen);

s         : 서버소켓의 파일 디스크립터를 인자로 전달.

addr      : 연결 요청을 수락할 클라이언트의 주소 정보를 저장할 변수의 포인터.

addrlen  : addr포인터가 가리키는 구조체의 크기를 저장하고 있는 변수의 포인터를 넘겨 준다.

 

TCP기반 클라이언트 구현

 

기본적인 함수 호출 순서

socket() -> connect() -> read(recv) & write(send) -> close()

소켓생성 -> 연결요청  ->      데이터 송수신          -> 연결 종료

 

int connect(int sockfd, struct sockadde *serv_addr, int addrlen);

sockfd : 미리 생성해 놓은 파일 디스크립터.

serv_addr : 연결 요청을 보낼 서버의 주소 정보를 지닌 구조체 변수의 포인터

addrlen : serv_addr 포인터가 가리키는 주소 정보 구조체 변수의 크기

 

반복적인(Iterative) 서버의 구현

클라이언트는 종료하더라도 특별한 오류 상황이 발생하지 않으면 서버의 실행은 계속 되는 것.

 

기본적인 함수 호출 순서

socket() ->     bind()          ->    listen()           -> accept()  -> read(recv)&write(send) -> close(client)   -> close(server)

                                                   (반복시작부분)                                                       (반복 끝부분)

소켓생성 -> 소켓에 주소할당 -> 연결요청대기상태 -> 연결 허용 ->데이터 송수신  -> 클라이언트 연결종료 -> 서버연결종료

 

에코 서버?

클라이언트가 전송해 주는 데이터를 그대로 되돌려 전송해 주는 기능의 서버.


TCP/IP 에서 에코 클라이언트 구현

 

TCP는 연결 지향 프로토콜로서 전송되는 데이터의 경계(boundary)가 없다.

서버에서 40바이트를 전송했는데, 클라이언트에서는 데이터를 수신하기 위한 버퍼가 있다.

그 버퍼 영역에 저장되어 클라이언트에서 read나 recv 함수를 호출할 때 마다, 버퍼에서 데이터를 읽어 들이는 것이다.


정리해보면,

TCP기반으로 데이터를 송수신하는 경우 데이터의 경계가 존재하지 않기 때문에 전송하고자 하는 데이터가 몇 개의 패킷으로

구성되어 전송될지 알 수 없다.

TCP기반으로 데이터를 송수신하기 위해서 소켓을 생성하는 경우 입력과 출력을 위한 버퍼가 커널에 의해 각각 생성된다.

이 버퍼들은 TCP를 적절히 수행하기 위해 반드시 필요하다.