TCP 서버-클라이언트 구조
1. 동작과 개념
- 서버는 먼저 실행하여 클라이언트가 접속하기를 기다린다. (listen)
- 클라이언트는 서버에 접속(connect)하여 데이터를 보낸다. (send)
- 서버는 클라이언트 접속을 수용하고(accept) 클라이너트가 보낸 데이터를 바당서(recv)처리한다.
- 서버는 처리한 데이터를 클라이언트에 보낸다. (send)
- 클라이언트는 서버가 보낸 데이터를 받아서(recv) 처리한다.
- 데이터를 주고받는 과정을 모두 마치면 접속을 끊는다. (closesocket)
2. 동작 원리
1) 서버는 소켓을 생성한 후 클라이언트가 접속하기를 기다린다.
- 이때 서버가 사용하는 소켓은 특정 포트번호(ex 9000번)와 결합되어 있어서 이 포트 번호로 접속하는 클라이언트만 수용할 수 있다.
2) 클라이언트가 서버에 접속한다.
- 이때 TCP프로토콜 수준에서 연결 설정을 위한 패킷교환이 일어난다.
3) TCP 프로토콜 연결 절차가 끝나면, 서버는 접속한 클라이언트와 통신할 수 있는 새로운 소켓을 생성한다.
- 이 소켓을 이용해 클라이언트와 데이터를 주고받는다.
- 기존 소켓은 새로운 클라이언트 젒공르 수용하는 용도로 계속 사용된다.
4) 두클라이언트가 접속한 후의 상태를 나타낸 것이다.
- 서버에는 소켓이 총 3개 존재하며, 이 중 두 소켓을 접속한 클라이언트와 통신하는 용도로 사용한다.
ex) 서버 1개와 n개의 TCP 클라언트의 통신
TCP 서버-클라이언트 분석
1. 동작과 개념
- 응용 프로그램의 관점에서 소켓은 운영체제의 TCP/IP 구현에서 제공하는 데이터 구조체를 참조하기 위한 메개체다.
- 응용프로그램이 통신하려면 다음과 같은 요소가 결정되어야 한다.
- 프로토콜 : 통신규약, 소켓을 생성할 때 결정
- 지역(local) IP주소와 지역 포트 번호 : 서버 또는 클라인트 자신의 주소이다.
- 원격(remote) IP주소와 원격 포트 번호 : 서버 또는 클라이언트가 통신하는 상대의 주소이다.
2. 소켓 함수
- 지역 주소와 원격 주소를 결정하고 TCP상태를 변경하기 위한 일련의 절차
1) TCP 서버 함수 : 일반적으로 TCP서버는 아래와 같은 순서로 소켓 함수를 호출한다.
- socket() 함수로 소켓을 생성함으로써 사용할 프초토콜을 결정한다.
- bind() 함수로 지역 IP주소와 지역 포트번호를 결정한다. (바인딩)
- listen() 함수로 TCP를 Listening 상태로 변경한다. (기다림)
- accept() 함수로 자신에게 접속한 클라이언트와 통신할 수 있는 새로운 소켓을 생성한다.
- 이때 원격 IP주소와 원격 포트번호가 결정된다.
- send(), recv() 등의 데이터 전송 함수로 클라이언트와 통신을 수행한 후, closesocket() 함수로 소켓을 닫는다.
- 새로운 클라이언트 접속이 들어올 때마다 4~5과정을 반복한다.
2) bind() 함수
: bind() 함수는 소켓의 지역 IP주소와 지역 포트 번호를 결정한다.
int bind (
SOCKET s,
const struct sockaddr *name,
int namelen
) ;
- S : 생성된 소켓/ 아닉 지역 IP주소와 지역 포트번호가 결정되지 않은 상태
- name : 소켓 주소 구조체를 지역 IP주소와 지역 포트번호로 초기화하여 전달
- namelen : 소켓 주소 구조체의 길이
3) listen() 함수
: listen() 함수는 소켓의 TCP 포트 상태를 LISTENNING으로 바꾼다. 이는 클라이언트 접속을 받아들일 수 있는 상태를 의미한다.
int listen (
SOCKET s,
int backlog
) ;
- S : bind() 함수로 지역 IP주소와 지역 포트 번호를 설정한 상태
- backlog : 서버가 당장 처리하지 않더라도 접속 가능한 클라이언트의 개수 ( accept() 함수를 호출하지 않음을 의미)
4) accept() 함수
: 접속한 클라이언트와 통신할 수 있도록 새로운 소켓을 생성해서 리턴한다.
또한 접속한 클라이언트의 주소정보도 알려준다.
SOCKET accept (
SOCKET s,
struct sockaddr *addr,
int *addrlen
) ;
- S : bind() 함수로 지역 IP주소와 지역 포트 번호를 설정하고 listen()함수로 TCP 상태를 listenning으로 변경한 상태
- addr : 소켓 주소 구조체를 전달하면 접속한 클라이언트의 주소 정보로 채워진다.
- addrlen : 정수형 변수를 addr이 가리키는 소켓 주소 구조체의 크기로 초기화한 후 전달한다.
3. TCP 클라이언트 함수
- 일반적으로 클라이언트는 아래의 그림과 같은 순서로 소켓 함수를 호출한다.
- socket() 함수로 소켓을 생성함으로써 사용할 프로토콜을 결정
- connect() 함수로 서버에 접속, 이때 원격 IP주소와 원격 포트 번호는 물론, 지역 IP주소와 지역 포트버호도 결정
- (연결요청)
- send(), recv() 등의 데이터 전송 함수로 서버와 통신한 후, closesocket()함수로 소켓을 닫는다.
1) connect() 함수
: connect() 함수는 TCP 프로토콜 수준에서 서버와 논리적 연결을 설정한다.
int connect (
SOCKET s,
const struct sockaddr *name,
int namelen
) ;
- S : 서버와 통신할 목적으로 생성된 소켓
- name : 소켓 주소 구조체를 서버 주소로 초기화하여 전달
- namelen : 소켓 주소 구조체의 길이
2) 소켓 버퍼
- 송신버퍼와 수신버퍼를 통틀어 소켓 버퍼라 한다.
- send() 와 recv()함수는 소켓 버퍼에 접근할 수 있게 만든 함수이다.
3) send() 함수
- send() 함수는 응용 프로그램 데이터를 운영체제의 송신버퍼에 복사함으로써 데이터를 전송한다.
- send() 함수는 복사에 성공하면 곧바로 리턴한다.
- 따라서 send()함수가 리턴했다고 실제 데이터가 전송된것이 아니며, 일정시간이 지나야만 하부 프로토콜을 통해 전송된다.
int send (
SOCKET s,
const char *buf,
int len,
int flags
);
- S : 통신할 대상과 연결된 소켓
- buf : 보낼 데이터를 담고 있는 응용 프로그램 버퍼의 주소
- len : 보낼 데이터 크기
- flags : send()함수의 동작을 바꾸는 옵션으로, 대부분 0사용
Send() 함수는 첫 번째 인자로 전달하는 소켓의 특성에 따라 다음과 같이 두 종류의 성공적인 리턴을 할 수 있다.
- 블로킹(blocking) 소켓
- 지금까지 생성한 소켓은 모두 블로킹 소켓이다
- 넌블로킹 소켓
- ioctlsocket() 함수를 이용하면 블로킹 소켓을 넌블로킹 소켓으로 바꿀 수 있다.
- 송신 버퍼의 여유 공간만큼 데이터를 복사한 후 실제 복사한 바이트 수를 리턴한다.
4) recv() 함수
- recv() 함수는 운영체제의 수신 버퍼에 도착한 데이터를 응용 프로그램 버퍼에 복사한다.
int recv (
SOCKET s,
char *buf,
int len,
int flags
);
- S : 통신할 대상과 연결된 소켓
- buf : 받은 데이터를 담고 있는 응용 프로그램 버퍼의 주소
- len : 운영체제의 수신 버퍼로부터 복사할 최대 데이터 크기이다. 이 값은 buf가 가리키는 으용 프로그램 버퍼보다 크지 않아야 한다.
- flags : recv()함수의 동작을 바꾸는 옵션, 대부분 0
recv() 함수는 두 종류의 성공적인 리턴을 할 수 있다.
- 수신 버퍼에 데이터가 도달한경우
- recv()함수의 세 번째 인자인 len보다 크지 않은 범위에서 가능하면 많은 데이터를 응용 프로그램 버퍼에 복사한 후 실제 복사한 바이트 수를 리턴한다.
- 이 경우 recv()함수의 리턴 값은 최소1, 최대 len이다.
- 접속이 정상 종료한 경우
- 상대편 으용 프로그램이 closesocket() 함수를 호출해 접속을 종료하면,
- TCP 프로토콜 수준에서 접속 종료를 위한 패킷 교환 절차가 일어난다.
- 이 경우 0을 리턴한다. (정상 종료)
'TCP-IP 윈도우 소켓 프로그래밍' 카테고리의 다른 글
[TCP/IP] 6장. 멀티 스레드 (0) | 2021.04.26 |
---|---|
[TCP/IP] 5장. 데이터 전송하기 (0) | 2021.04.14 |
[TCP/IP] 3장. 소켓 주소 구조체 다루 (0) | 2021.04.09 |
[TCP/IP] 2장. 윈도우 소켓 시작하기 (0) | 2021.04.07 |
[TCP/IP] 1장. 네트워크와 소켓 프로그래밍 (0) | 2021.04.06 |