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

Slides:



Advertisements
Similar presentations
Network Programming:
Advertisements

03 변수와 자료형 세종대학교 최옥경 교수 참고 : 한빛미디어 뇌를 자극하는 C, INFINITY Perfect C.
Python Socket/HTTP overmania. 목표  소켓을 이용하여 기본적인 서버 - 클라이언트 모델을 구현할 수 있다.  간단한 웹서버를 소켓을 이용하여 작성할 수 있다.
Java Socket 통신 이개혁 정대준.
6장. 멀티스레드 멀티스레드 프로그래밍의 필요성을 이해하고 기본 개념을 익힌다.
Chapter 09. 소켓 입출력 모델(I).
Understanding of Socket and File I/O
13장 소켓.
Chapter 06. UDP 서버/클라이언트.
TCP/IP Socket Cover Slide 조태문.
Network Lab. Young-Chul Hwang
TCP Client/Server Program
TCP/IP 소켓 프로그래밍 - C 버전 중에서
Department of Computer Engineering
4장. 소켓 유형과 프로토콜 Network Lab. 이 원 구 1.
PHP 웹 프로그래밍 (PHP Web Programming) 네트워크 프로그래밍 문양세 강원대학교 IT대학 컴퓨터과학전공.
TCP/IP Socket Cover Slide 조태문.
인공지능실험실 석사 2학기 김승겸 TCP/IP Socket Programming… 제 10장 멀티태스킹 기반의 서버구현 인공지능실험실 석사 2학기 김승겸
Chapter 03. 소켓 주소 구조체 다루기.
TCP Client/Server Program
Network Lab. Seoung Hyeon, Lee
얇지만 얇지 않은 TCP/IP 소켓 프로그래밍 C 2판
컴퓨터 네트워크 PART 03 프로그래밍 (chapter 01 Socket 프로그래밍) 임효택
호스트이름과 네트워크이름 찾기 (Hostname and Network Name Lookups)
Internet Address Conversion Functions
3장. 소켓 주소 구조체 다루기 소켓 주소 구조체의 정의와 초기화 방법을 익힌다.
6장 비연결형 지향 프로토콜 Database Lab 강 우 석.
11 소켓 프로그래밍 기초.
인터넷 주소 변환 School of Electronics and Information. Kyung Hee University.
14장 소켓.
18장 Practical Network Project
제 12장 I/O멀티플렉싱(Multiplexing)
Choi Seong Yun 네트워크 프로그래밍 Choi Seong Yun
Using Standard I/O on Sockets
Chapter 02. 윈도우 소켓 시작하기.
한남대학교 컴퓨터공학과 컴퓨터 네트워크 실험실
Department of Computer Engineering
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 7장 소켓 연결의 우아한 종료 인공지능실험실 석사 2학기 이희재
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
(Web Programming & Practice)
Department of Computer Engineering
Homework 6… 12월 2일(금) 11:59pm까지 자신의 이름과 학번을 출력해 주는 유닉스/리눅스 네트워크 소켓 서버 프로그램 과 클라이언트 프로그램 을 작성해 보세요 참고 (실습1) Hello 프로그램 helloserver.c helloclient.c 컴파일.
7장. UDP 서버-클라이언트 UDP 서버-클라이언트의 기본 구조와 동작 원리를 이해한다.
Chapter 8 연결형 프로토콜 서버 발표자 : SE Lab 황 성 하
Department of Computer Engineering
Chapter 06. UDP 서버/클라이언트.
Chapter 12. 직렬 통신과 무선 프로토콜.
Advanced Socket Programming
Department of Computer Engineering
프로젝트 발표 순서 12/7(수), 팀 별 15분 발표순서 PPT (팀 별 이름, 구현 내용, 결과-그래프 포함) 각 기법당
13장 고급 입출력 함수 박사 4학기 최 성자.
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
7장. UDP 서버-클라이언트 UDP 서버-클라이언트의 기본 구조와 동작 원리를 이해한다.
Chapter 09. 소켓 입출력 모델(I).
School of Electronics and Information. Kyung Hee University.
네트워크 프로그래밍의 이해 School of Electronics and Information.
윤성우의 열혈 TCP/IP 소켓 프로그래밍 윤성우 저 열혈강의 TCP/IP 소켓 프로그래밍 개정판
제어문 & 반복문 C스터디 2주차.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Chapter 16 Socket Interface.
Department of Computer Engineering
윤성우의 열혈 TCP/IP 소켓 프로그래밍 윤성우 저 열혈강의 TCP/IP 소켓 프로그래밍 개정판
6장 반복제어문 for 문 while 문 do while 문 기타 제어문.
MONSTER CAR 구정재 한석우 김재형.
Chapter 04. TCP 서버/클라이언트.
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express.
Chapter 03. 소켓 주소 구조체 다루기.
소켓의 생성과 프로토콜의 설정 School of Electronics and Information.
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
Department of Computer Engineering
Presentation transcript:

TCP 서버/클라이언트 Chapter 04. * 학습목표 TCP 서버/클라이언트의 기본 구조와 동작 원리를 이해함 애플리케이션 프로토콜의 필요성을 이해하고, 메시지 설계 기법을 익힘

TCP 서버/클라이언트 동작 원리 - (1) TCP 서버/클라이언트 예 웹 서버 웹 클라이언트 웹 클라이언트 GET / HTTP/1.1 Accept: image/gif, ... <HTML> <HEAD>...</HEAD>... 웹 서버 웹 클라이언트 웹 클라이언트

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

TCP 서버/클라이언트 동작 원리 - (3) TCP 서버/클라이언트 동작 원리 TCP 서버 대기 클라이언트 접속 TCP 클라이언트 #1 클라이언트 접속 (1) 서버는 소켓을 생성 후 클라이언트를 기다림 포트번호 : 9000 (2) 클라이언트 접속함 (연결설정)

TCP 서버/클라이언트 동작 원리 - (4) TCP 서버/클라이언트 동작 원리 (계속) TCP 서버 대기 통신 TCP 클라이언트 #1 클라이언트 #2 통신 대기 (3) 클라이언트 새로운 소켓을 생성 (4) 1명의 클라이언트가 새로 접속하여 새로운 소켓을 생성한 상태

TCP 서버/클라이언트 동작 원리 - (5) TCP 서버/클라이언트 동작 원리 (계속) TCP 서버/클라이언트 예제 동작 방식 클라이언트 #1 대기 클라이언트 #n . . . (5) N명의 클라이언트가 새로 접속하여 새로운 소켓을 생성한 상태 (1 : 1 통신 구조) TCP 서버/클라이언트 예제 동작 방식 TCP 클라이언트 TCP 서버 fgets() send() printf() recv() 화면 화면 데이터 데이터

TCP 서버/클라이언트 분석 TCP/IP 소켓 통신을 위해 필요한 요소 소켓 데이터 구조체 ① 프로토콜 소켓을 생성할 때 결정 ② 지역(local) IP 주소와 지역 포트 번호 서버 또는 클라이언트 자신의 주소 ③ 원격(remote) IP 주소와 원격 포트 번호 서버 또는 클라이언트가 통신하는 상대방의 주소 소켓 데이터 구조체 서버 지역 IP 주소 지역 포트 번호 원격 IP 주소 원격 포트 번호 클라이언트 애플리케이션 운영체제 네트워크 • • •

TCP 서버 함수 - (1) TCP 서버 함수 socket() bind() recv() send() closesocket() connect() listen() accept() 네트워크

TCP 서버 함수 - (2) bind() 함수 bind() 함수 사용 예 (예제 1 참조) 서버의 지역 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()");

TCP 서버 함수 - (3) listen() 함수 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()");

TCP 서버 함수 - (4) accept() 함수 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 }

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 }

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

TCP 클라이언트 함수 - (1) TCP 클라이언트 함수 네트워크 socket() bind() recv() send() closesocket() TCP 서버 TCP 클라이언트 connect() listen() accept() 네트워크

TCP 클라이언트 함수 - (2) connect() 함수 connect() 함수 사용 예 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()");

데이터 전송 함수 - (1) 소켓 데이터 구조체 서버 클라이언트 네트워크 지역 IP 주소 지역 포트 번호 원격 IP 주소 원격 포트 번호 클라이언트 애플리케이션 운영체제 네트워크 • • • 수신 버퍼 송신 버퍼

데이터 전송 함수 - (2) send() 함수 recv() 함수 애플리케이션 데이터를 송신 버퍼에 복사함으로써 궁극적으로 하부 프로토콜 (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

데이터 전송 함수 - (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 }

데이터 전송 함수 - (4) recvn( ) 함수 동작 원리 buf ptr left len 읽은 데이터

데이터 전송 함수 - (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;

데이터 전송 함수 - (6) 데이터 전송 함수 사용 예 – TCP 클라이언트 (계속) 096 // 데이터 보내기 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) break; 113 // 받은 데이터 출력 114 buf[retval] = '\0'; // 맨 끝에 0을 입력함. 115 printf("[TCP 클라이언트] %d바이트를 받았습니다.\n", retval); 116 printf("[받은 데이터] %s\n", buf); 117 }

데이터 전송 함수 - (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 }

실습 예제 – (1) 마무리 하시오.

애플리케이션 프로토콜과 메시지 설계 - (1) 애플리케이션 프로토콜 애플리케이션 프로토콜 예 애플리케이션 수준에서 주고 받는 데이터의 형식과 의미, 처리 방식 등을 정의한 프로토콜 애플리케이션 프로토콜 예 네트워크

애플리케이션 프로토콜과 메시지 설계 - (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; // 선 색상 };

애플리케이션 프로토콜과 메시지 설계 - (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; // 선 색상

메시지 설계 시 고려 사항 경계 구분 [송신자] ① 항상 고정 길이 데이터를 보낸다. ② 경계 구분을 위해 특별한 표시(EOR; End Of Record)를 삽입한다. ③ 보낼 데이터 길이를 고정 길이 데이터로 보낸 후, 가변 길이 데이터를 이어서 보낸다. [수신자] ① 항상 고정 길이 데이터를 받는다. ② EOR이 나올 때까지 데이터를 읽은 후 처리한다. ③ 고정 길이 데이터를 읽어 뒤따라올 데이터의 길이를 알아낸다. 이 길이만큼 데이터를 읽어 처리한다. 바이트 정렬 빅 엔디안 방식으로 통일 멤버 정렬 구조체(공용체, 클래스 포함) 멤버의 시작 주소에 대한 제약 사항 #pragma pack 컴파일러 명령을 사용

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