본문 바로가기
programing/Networks

TCP 기반 서버 / 클라

by RedWiz 2015. 5. 13.

 

TCP_Calculator.zip

 

 

- TCP( Transmission Control Protocol )

 

- UDP( User Datagram Protocol )

 

- OSI7 계층

 Physical -> Datalink -> Network -> Transport -> Session -> Presentation -> Application

 

- TCP/IP 프로토콜 탄생 배경

인터넷을 통한 효율적인 데이터 송수신

-> 영역별로 작게 문제를 나눔

cf. 계층화 장점

: 표준화 작업을 통한 개방형 시스템(Open System) + 각 층을 개발하며 다른 층을 고려할 필요 없음

 

- LINK 계층 : 물리적인 영역의 표준화

LAN, WAN, MAN과 같은 네트워크 표준과 관련 프로토콜 정의

 

- IP 계층 (Network) : 데이터 경로 검색

비 연결지향적, 비 신뢰성

경로를 선택해주지만 경로가 일정하지 않음

전송 도중 문제가 생겨 데이터 손실이나 오류가 발생해도 해결안함 => 오류 대비가 없음

 

- TCP/UDP 계층 (Transport) : 경로 정보 바탕으로 실제 데이터 송수신 담당

TCP : 신뢰성 있는 데이터의 전송( 전송 확인 절차를 거침 )

UDP : 보내고 신경 안씀

 

- APPICATION 계층

프로그래밍에 있어 이 아래 계층에서 일어나는 일들은 신경 안씀

네트워크 프로그래밍은 APPLICATION 프로토콜의 설계 및 구현이 상당부분 차지

 

- 연결 요청 대기 상태

int listen(

SOCKET s,                // 연결 요청 대기 상태에 두고자 하는 서버 소켓

int backlog                // 연결 요청 대기 큐의 크기 정보 전달, 연결 요청 최대 대기 수를 설정

);    // 성공 : 0, 실패 : SOCKET_ERROR

> 이전에 클라의 connect 함수 호출시 오류

 

- 연결 요청 수락

SOCKET accept(

SOCKET s,

sockaddr* addr,             // 클라의 주소정보 담을 변수 주소

int* addrlen                    // 두번재 인수의 크기 변수 주소

);    // 성공 : 생성된 소켓의 핸들, 실패 : INVALID_SOCKET

 

- 연결 요청

int  connect(

SOCKET s,                     // 클라이언트 소켓 핸들

cosnt sockaddr* name,    // 연결요청할 서버의 주소 정보

int namelen                     // 두 번째 변수 크기

);    // 성공 : 0 , 실패 : SOCKET_ERROR

 

- TCP기반 서버, 클라 함수 호출 관계 

  <SEVER>                  <CLIENT>

   socket()

       ↓

     bind()

       ↓                                 socket()

    listen()                                ↓

       ↓        <------┬------  connet()

   accept()             │                |

       ↓         <-----┘                ↓

send()/recv()   <------->   send()/recv()

       ↓                                      ↓

    close()        <------->       close()

 

> 클라이언트는 서버에서 listen() 호출 이후 connet() 호출이 가능

> 클라이언트가 connect() 호출하기에 앞서 서버가 accept()를 먼저 호출 할 수 있음

=> 클라이언트가 connect() 호출할 때까지 accept() 함수가 호출된 위치에서 블로킹 상태에 놓임

 

* recv() 함수는 호출시 연결된 쪽에서 send() 호출까지 대기 상태가 된다.

 

* read()/ write() 간의 통신은 문자열로 통신함

=> 전송 포멧에서 자료형 크기가 다른 데이터 보낼시 고려 해야함

cf. int(4byte)와 char(1byte)의 경우

int -> char : int를 1byte 씩 쪼개서 char배열 공간에 넣어야함

char -> int : char 배열이 아닌 1byte 인경우 전송 받을 int는 나머지 자리를 0으로 초기화 시켜줘야함

 

- TCP 소켓에 입출력 버퍼 존재

> 입출력 버퍼는 TCP소켓 각각에 대해 별도로 존재

> 입출력 버퍼는 소켓 생성시 자동으로 생성

> 소켓을 닫아도 출력 버퍼의 데이터는 계속 전송

> 소켓을 닫으면 입력 버퍼의 데이터는 소멸         => 보낼 데이터는 남아있고 받을 데이터는 사라짐

 

 

< TCP 내부 동작원리 >

- 상대 소켓과의 연결

* Three-way handshaking

> SYN : 동기화 메시지

> ACK : 응답 메시지

> SEQ 1000 : 보내는 패킷이 1000번이니 받았으면 1001번을 보내라

> SEQ 2000, ACK 1001 : 보내는 패킷이 2000이니 받았으면 2001번을 보내고

1000 패킷은 잘 받았으니 1001 보냄

> SEQ 1001, ACK 2001 : SEQ가 2000인 패킷 잘 받았으니 다음엔 SEQ가 2001인 패킷 전송 바람

 

- 상대 소켓과 데이터 송수신

> ACK 번호 = SEQ 번호 + 전송된 바이트 크기 + 1

(+ 1 : Three-way handshaking에서 보였듯 다음번 전달될 SEQ 번호 알리기 위함)

 

* 송신 오류시

> 중간에 문제 발생시 Time Out 이후 재전송

 

- 상대소켓과의 연결 종료

* Four-way handshaking

> FIN : 종료 메시지

> HOST B에서 (ACK : 5001)이 두번 전송된 이유

->앞서 전송한 ACK 메시지가 수신된 이후 HOST A로부터  데이터 수신이 없었으므로