28
Chapter 04. TCP 서서 / 서서서서서 * 서서서서 TCP 서서 / 서서서서서서 서서 서서서서 서서서 서서서 TCP 서서서서서서 서서서 서서서 서서 서서서 서서 서서서서서서 서서서서서 서서서서서서서 , 서서서 서서 서서서 서서

Chapter 04. TCP 서버 / 클라이언트

Embed Size (px)

DESCRIPTION

Chapter 04. TCP 서버 / 클라이언트. * 학습목표. TCP 서버 / 클라이언트의 기본 구조 와 동작 원리 를 이해함 TCP 애플리케이션 작성에 필요한 소켓 함수 를 익힘 애플리케이션 프로토콜의 필요성 을 이해 하고 , 메시지 설계 기법 을 익힘. TCP 서버 / 클라이언트 동작 원리 - (1). TCP 서버 / 클라이언트 예. GET / HTTP/1.1 Accept: image/gif,. .... 웹 서버. 웹 클라이언트. - PowerPoint PPT Presentation

Citation preview

Page 1: Chapter  04. TCP  서버 / 클라이언트

Chapter 04.

TCP 서버 / 클라이언트* 학습목표

• TCP 서버 / 클라이언트의 기본 구조와 동작 원리를 이해함• TCP 애플리케이션 작성에 필요한 소켓 함수를 익힘• 애플리케이션 프로토콜의 필요성을 이해하고 , 메시지 설계 기법을 익힘

Page 2: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 2 - ehanbit.net

TCP 서버 / 클라이언트 동작 원리 - (1)

• TCP 서버 / 클라이언트 예

웹 클라이언트 웹 클라이언트

웹 서버GET / HTTP/1.1Accept: image/gif, ...

<HTML><HEAD>...</HEAD>...

Page 3: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 3 - ehanbit.net

TCP 서버 / 클라이언트 동작 원리 - (2)

• TCP 서버 / 클라이언트 동작 방식

TCP 서버 TCP 클라이언트

listen

accept

recv

send

connect

send

recv

네트워크

• TCP 서버 / 클라이언트 동작 방식① 서버는 먼저 실행하여 클라이언트가 접속하기를 기다린다 (listen).② 클라이언트가 서버에게 접속 (connect) 하여 데이터를 보낸다 (send).③ 서버는 클라이언트 접속을 수용하고 (accept), 클라이언트가 보낸 데이터를 받아서 (recv) 처리한다 .④ 서버는 처리한 데이터를 클라이언트에게 보낸다 (send).⑤ 클라이언트는 서버가 보낸 데이터를 받아서 (recv) 자신의 목적에 맞게 사용한다 .

Page 4: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 4 - ehanbit.net

TCP 서버 / 클라이언트 동작 원리 - (3)

• TCP 서버 / 클라이언트 동작 원리

TCP 서버

대기

TCP 서버

TCP 클라이언트 #1

클라이언트 접속

(1) 서버는 소켓을 생성 후

클라이언트를 기다림

포트번호 : 9000

(2) 클라이언트 접속함 ( 연결설정 )

Page 5: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 5 - ehanbit.net

TCP 서버 / 클라이언트 동작 원리 - (4)

• TCP 서버 / 클라이언트 동작 원리 ( 계속 )

TCP 서버

TCP 클라이언트 #1

TCP 클라이언트 #2

통신 통신대기

TCP 서버

TCP 클라이언트 #1

통신

대기

(3) 클라이언트 새로운 소켓을 생성 (4) 1 명의 클라이언트가 새로 접속하여 새로운

소켓을 생성한 상태

Page 6: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 6 - ehanbit.net

TCP 서버 / 클라이언트 동작 원리 - (5)

• TCP 서버 / 클라이언트 동작 원리 ( 계속 )

TCP 서버

TCP 클라이언트 #1

대기

TCP 클라이언트 #n. . .

. . . . . .

. . .

• TCP 서버 / 클라이언트 예제 동작 방식

TCP 클라이언트 TCP 서버

fgets() send()

printf()

recv() printf()

send()recv()

(5) N 명의 클라이언트가 새로 접속하여 새로운

소켓을 생성한 상태 (1 : 1 통신 구조 )

화면 화면데이터 데이터

Page 7: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 7 - ehanbit.net

TCP 서버 / 클라이언트 분석

• TCP/IP 소켓 통신을 위해 필요한 요소① 프로토콜

• 소켓을 생성할 때 결정② 지역 (local) IP 주소와 지역 포트 번호

• 서버 또는 클라이언트 자신의 주소③ 원격 (remote) IP 주소와 원격 포트 번호

• 서버 또는 클라이언트가 통신하는 상대방의 주소

서버

지역 IP 주소지역 포트 번호원격 IP 주소원격 포트 번호

클라이언트

지역 IP 주소지역 포트 번호원격 IP 주소원격 포트 번호

애플리케이션

운영체제

네트워크

• • • • • •

• 소켓 데이터 구조체

Page 8: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 8 - ehanbit.net

TCP 서버 함수 - (1)

• TCP 서버 함수

socket()

bind()

recv()

send()

closesocket()

socket()

send()

recv()

closesocket()

TCP 서버 TCP 클라이언트

connect()

listen()

accept()

네트워크

Page 9: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 9 - ehanbit.net

TCP 서버 함수 - (2)

• bind() 함수– 서버의 지역 IP 주소와 지역 포트 번호를 결정

int bind ( SOCKET s, // 소켓생성 결과값 const struct sockaddr* name, // 소켓구조체 ( 주소 , 포트번호 , 프로토콜타입 ) int namelen // 소켓구조체 크기) ; 성공 : 0, 실패 : SOCKET_ERROR

• bind() 함수 사용 예 ( 예제 1 참조 )

050 SOCKADDR_IN serveraddr;051 ZeroMemory (&serveraddr, sizeof(serveraddr));052 serveraddr.sin_family = AF_INET;053 serveraddr.sin_port = htons(9000);054 serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);055 retval = bind(listen_sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr));056 if(retval == SOCKET_ERROR) err_quit("bind()");

Page 10: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 10 - ehanbit.net

TCP 서버 함수 - (3)

• listen() 함수– 소켓과 결합된 TCP 포트 상태를 LISTENING 으로 변경

int listen ( SOCKET s, // 소켓생성 결과값 int backlog // 연결큐의 길이 ( 최대 접속자수 ) ) ; 성공 : 0, 실패 : SOCKET_ERROR

• listen() 함수 사용 예

059 retval = listen (listen_sock, SOMAXCONN);060 if(retval == SOCKET_ERROR) err_quit("listen()");

Page 11: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 11 - ehanbit.net

TCP 서버 함수 - (4)• accept() 함수

– 접속한 클라이언트와 통신할 수 있도록 새로운 소켓을 생성하여 리턴– 접속한 클라이언트의 IP 주소와 포트 번호를 알려줌

SOCKET accept ( SOCKET s, // 소켓 ( 클라이언트전용 ) 생성 결과값 struct sockaddr* addr, // 클라이언트의 IP 주소와 포트번호 지정된 메모리에 저장 int* addrlen // 지정된 메모리 주소값) ; 성공 : 새로운 소켓 , 실패 : INVALID_SOCKET

• accept() 함수 사용 예062 // 데이터 통신에 사용할 변수063 SOCKET client_sock;064 SOCKADDR_IN clientaddr;065 int addrlen;...068 while(1){069 // accept( )070 addrlen = sizeof(clientaddr);071 client_sock = accept (listen_sock, (SOCKADDR *)&clientaddr, &addrlen);072 if(client_sock == INVALID_SOCKET){073 err_display("accept()");074 continue;075 }

Page 12: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 12 - ehanbit.net

TCP 서버 함수 - (5)

• accept() 함수 사용 예 ( 계속 )

076 printf("\n[TCP 서버 ] 클라이언트 접속 : IP 주소 =%s, 포트 번호 =%d\n", 077 inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));078 079 // 클라이언트와 데이터 통신080 while(1){...101 }102 103 // closesocket()104 closesocket(client_sock);105 printf("[TCP 서버 ] 클라이언트 종료 : IP 주소 =%s, 포트 번호 =%d\n", 106 inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));107 }

Page 13: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 13 - ehanbit.net

실습 예제 – (1)

• 소요시간 : 1 시간 30 분 . • 직접 코딩해서 실습할 것 .• 매우 중요한 예제임 .• 각 라인별로 소스를 분석하시오 .

Page 14: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 14 - ehanbit.net

TCP 클라이언트 함수 - (1)

• TCP 클라이언트 함수

socket()

bind()

recv()

send()

closesocket()

socket()

send()

recv()

closesocket()

TCP 서버 TCP 클라이언트

connect()

listen()

accept()

네트워크

Page 15: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 15 - ehanbit.net

TCP 클라이언트 함수 - (2)

• connect() 함수– 서버에게 접속하여 TCP 프로토콜 수준의 연결 설정

int connect ( SOCKET s, // 서버와 통신을 하기 위해 만든 소켓 const struct sockaddr* name, // 서버 주소 , 포트번호 -> 특정 주소값에 저장 int namelen // 소켓 주소 구조체 변수의 크기 ) ; 성공 : 0, 실패 : SOCKET_ERROR

• connect() 함수 사용 예

070 SOCKADDR_IN serveraddr;071 serveraddr.sin_family = AF_INET;072 serveraddr.sin_port = htons(9000);073 serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");074 retval = connect(sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr));075 if(retval == SOCKET_ERROR) err_quit("connect()");

Page 16: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 16 - ehanbit.net

데이터 전송 함수 - (1)

• 소켓 데이터 구조체

서버

지역 IP 주소지역 포트 번호원격 IP 주소원격 포트 번호

클라이언트

지역 IP 주소지역 포트 번호원격 IP 주소원격 포트 번호

애플리케이션

운영체제

네트워크

• • • • • •

수신 버퍼송신 버퍼

Page 17: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 17 - ehanbit.net

데이터 전송 함수 - (2)

• send() 함수– 애플리케이션 데이터를 송신 버퍼에 복사함으로써 궁극적으로 하부 프로토콜 (Ex. TCP/IP) 에 의해 데이터가 전송

int send ( SOCKET s, // 통신할 대상과 연결된 소켓 const char* buf, // 보낼 데이터를 담고 있는 애플리케이션 버퍼 주소 int len, // 보낼 데이터 크기 int flags // send( ) 함수의 동작을 바꾸는 옵션 ( 보통 0)); 성공 : 보낸 바이트 수 , 실패 : SOCKET_ERROR

• recv() 함수– 수신 버퍼에 도착한 데이터를 애플리케이션 버퍼로 복사

int recv ( SOCKET s, // 통신할 대상과 연결된 소켓 char* buf, // 받은 데이터를 저장할 애플리케이션 버퍼의 주소 int len, // 수신 버퍼로부터 복사할 최대 데이터 크기 int flags // recv( ) 함수의 동작을 바꾸는 옵션 ( 보통 0)); 성공 : 받은 바이트 수 또는 0 ( 연결 종료 시 ), 실패 : SOCKET_ERROR

Page 18: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 18 - ehanbit.net

데이터 전송 함수 - (3)

• recvn() 함수 : 만약 수신할 전체 크기를 알고 있다면

037 int recvn (SOCKET s, char *buf, int len, int flags)038 {039 int received;040 char *ptr = buf;041 int left = len; // left : 보낼 총 바이트 수042 043 while (left > 0){044 received = recv (s, ptr, left, flags);045 if (received == SOCKET_ERROR) 046 return SOCKET_ERROR;047 else if (received == 0) 048 break;049 left -= received;050 ptr += received;051 }052 053 return (len - left);054 }

Page 19: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 19 - ehanbit.net

데이터 전송 함수 - (4)

• recvn( ) 함수 동작 원리

buf

ptr left

buflen

ptr left

len

읽은 데이터

Page 20: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 20 - ehanbit.net

데이터 전송 함수 - (5)

• 데이터 전송 함수 사용 예 – TCP 클라이언트

078 char buf[BUFSIZE+1];079 int len;...082 while(1){083 // 데이터 입력084 ZeroMemory(buf, sizeof(buf));085 printf("\n[ 보낼 데이터 ] ");086 if(fgets(buf, BUFSIZE+1, stdin) == NULL) // 사용자로부터 문자열 입력087 break;088 089 // '\n' 문자 제거090 len = strlen(buf);091 if(buf[len-1] == '\n')092 buf[len-1] = '\0';093 if(strlen(buf) == 0)094 break;

Page 21: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 21 - ehanbit.net

데이터 전송 함수 - (6)

• 데이터 전송 함수 사용 예 – TCP 클라이언트 ( 계속 )

096 // 데이터 보내기097 retval = send(sock, buf, strlen(buf), 0);098 if(retval == SOCKET_ERROR){099 err_display("send()");100 break;101 }102 printf("[TCP 클라이언트 ] %d 바이트를 보냈습니다 .\n", retval);103 104 // 데이터 받기105 retval = recvn(sock, buf, retval, 0);106 if(retval == SOCKET_ERROR){107 err_display("recv()");108 break;109 }110 else if(retval == 0)111 break;113 // 받은 데이터 출력114 buf[retval] = '\0'; // 맨 끝에 0 을 입력함 .115 printf("[TCP 클라이언트 ] %d 바이트를 받았습니다 .\n", retval);116 printf("[ 받은 데이터 ] %s\n", buf);117 }

Page 22: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 22 - ehanbit.net

데이터 전송 함수 - (7)

• 데이터 전송 함수 사용 예 – TCP 서버066 char buf[BUFSIZE+1];...080 while(1){081 // 데이터 받기082 retval = recv (client_sock, buf, BUFSIZE, 0);083 if(retval == SOCKET_ERROR){084 err_display("recv()");085 break;086 }087 else if (retval == 0)088 break;090 // 받은 데이터 출력091 buf[retval] = '\0';092 printf("[TCP/%s:%d] %s\n", inet_ntoa(clientaddr.sin_addr),093 ntohs(clientaddr.sin_port), buf);095 // 데이터 보내기096 retval = send(client_sock, buf, retval, 0);097 if(retval == SOCKET_ERROR){098 err_display("send()");099 break;100 }101 }

Page 23: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 23 - ehanbit.net

실습 예제 – (1)

• 마무리 하시오 .

Page 24: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 24 - ehanbit.net

애플리케이션 프로토콜과 메시지 설계 - (1)

• 애플리케이션 프로토콜– 애플리케이션 수준에서 주고 받는 데이터의 형식과 의미 , 처리 방식 등을 정의한 프로토콜

• 애플리케이션 프로토콜 예

네트워크

Page 25: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 25 - ehanbit.net

애플리케이션 프로토콜과 메시지 설계 - (2)

• 메시지 정의 ① - 직선을 그리기 ( 타입 없음 )

• 메시지 정의 ② - 원 그리기 ( 타입 없음 )

struct DrawMessage1{ int x1, y1; // 선의 시작점 int x2, y2; // 선의 끝점 int width; // 선 두께 int color; // 선 색상};

struct DrawMessage2{ int x1, y1; // 원의 중심 좌표 int r; // 원의 반지름 int fillcolor; // 내부 색상 int width; // 선 두께 int color; // 선 색상};

Page 26: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 26 - ehanbit.net

애플리케이션 프로토콜과 메시지 설계 - (3)

• 메시지 정의 ③ - 직선 및 원 그리기 ( 타입 존재 )

struct DrawMessage1{ int type; // = LINE int x1, y1; // 선의 시작점 int x2, y2; // 선의 끝점 int width; // 선 두께 int color; // 선 색상};

struct DrawMessage2{ int type; // = CIRCLE int x1, y1; // 원의 중심 좌표 int r; // 원의 반지름 int fillcolor; // 내부 색상 int width; // 선 두께 int color; // 선 색상};

Page 27: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 27 - ehanbit.net

메시지 설계 시 고려 사항

• 경계 구분[ 송신자 ]

① 항상 고정 길이 데이터를 보낸다 .② 경계 구분을 위해 특별한 표시 (EOR; End Of Record) 를 삽입한다 .③ 보낼 데이터 길이를 고정 길이 데이터로 보낸 후 , 가변 길이 데이터를 이어서 보낸다 .

[ 수신자 ]① 항상 고정 길이 데이터를 받는다 .② EOR 이 나올 때까지 데이터를 읽은 후 처리한다 .③ 고정 길이 데이터를 읽어 뒤따라올 데이터의 길이를 알아낸다 . 이 길이만큼 데이터를

읽어 처리한다 .

• 바이트 정렬– 빅 엔디안 방식으로 통일

• 멤버 정렬– 구조체 ( 공용체 , 클래스 포함 ) 멤버의 시작 주소에 대한

제약 사항– #pragma pack 컴파일러 명령을 사용

Page 28: Chapter  04. TCP  서버 / 클라이언트

IT COOKBOOKIT COOKBOOK

한빛미디어㈜ - 28 - ehanbit.net

실습 예제 – (2)

• 소요시간 : 1 시간 30 분 . • 직접 코딩해서 실습할 것 .• 앞 예제랑 비교하면서 코드 분석할 것 .