Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Chapter 04. TCP 서버/클라이언트."— Presentation transcript:

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

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

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

4 TCP 서버/클라이언트 동작 방식 TCP 서버/클라이언트 동작 원리 (2/6) TCP 서버 TCP 클라이언트 listen
accept recv send connect 네트워크

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

6 TCP 서버/클라이언트 동작 원리 TCP 서버/클라이언트 동작 원리 (4/6) TCP 서버 대기 TCP 서버 TCP
클라이언트 #1 클라이언트 접속

7 TCP 서버/클라이언트 동작 원리 (cont’d)
클라이언트 #1 통신 대기 TCP 서버 TCP 클라이언트 #1 클라이언트 #2 통신 대기

8 TCP 서버/클라이언트 동작 원리 (cont’d)
클라이언트 #1 대기 클라이언트 #n . . .

9 예제 동작 방식 TCP 서버/클라이언트 예제 TCP 클라이언트 TCP 서버 fgets() send() printf()
recv()

10 TCP/IP 소켓 통신을 위해 필요한 요소 ① 프로토콜 ② 지역(local) IP 주소와 지역 포트 번호
소켓을 생성할 때 결정 ② 지역(local) IP 주소와 지역 포트 번호 서버 또는 클라이언트 자신의 주소 ③ 원격(remote) IP 주소와 원격 포트 번호 서버 또는 클라이언트가 통신하는 상대방의 주소

11 소켓 데이터 구조체 TCP 서버/클라이언트 분석 (2/2) 서버 클라이언트 애플리케이션 운영체제 네트워크 지역 IP 주소
지역 포트 번호 원격 IP 주소 원격 포트 번호 클라이언트 애플리케이션 운영체제 네트워크 • • •

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

13 bind() 함수 서버의 지역 IP 주소와 지역 포트 번호를 결정 TCP 서버 함수 (2/8) int bind (
SOCKET s, const struct sockaddr* name, int namelen ) ; 성공: 0, 실패: SOCKET_ERROR

14 bind() 함수 사용 예 TCP 서버 함수 (3/8) 050 SOCKADDR_IN serveraddr;
ZeroMemory(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(9000); serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); retval = bind(listen_sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr)); if(retval == SOCKET_ERROR) err_quit("bind()");

15 listen() 함수 소켓과 결합된 TCP 포트 상태를 LISTENING으로 변경 TCP 서버 함수 (4/8)
int listen ( SOCKET s, int backlog ) ; 성공: 0, 실패: SOCKET_ERROR

16 listen() 함수 사용 예 TCP 서버 함수 (5/8)
retval = listen(listen_sock, SOMAXCONN); if(retval == SOCKET_ERROR) err_quit("listen()");

17 accept() 함수 접속한 클라이언트와 통신할 수 있도록 새로운 소켓을 생성하여 리턴
TCP 서버 함수 (6/8) accept() 함수 접속한 클라이언트와 통신할 수 있도록 새로운 소켓을 생성하여 리턴 접속한 클라이언트의 IP 주소와 포트 번호를 알려줌 SOCKET accept ( SOCKET s, struct sockaddr* addr, int* addrlen ) ; 성공: 새로운 소켓, 실패: INVALID_SOCKET

18 accept() 함수 사용 예 TCP 서버 함수 (7/8) 062 // 데이터 통신에 사용할 변수
// 데이터 통신에 사용할 변수 SOCKET client_sock; SOCKADDR_IN clientaddr; int addrlen; ... while(1){ // accept() addrlen = sizeof(clientaddr); client_sock = accept(listen_sock, (SOCKADDR *)&clientaddr, &addrlen); if(client_sock == INVALID_SOCKET){ err_display("accept()"); continue; }

19 accept() 함수 사용 예 (cont’d)
TCP 서버 함수 (8/8) accept() 함수 사용 예 (cont’d) printf("\n[TCP 서버] 클라이언트 접속: IP 주소=%s, 포트 번호=%d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); 078 // 클라이언트와 데이터 통신 while(1){ ... } 102 // closesocket() closesocket(client_sock); printf("[TCP 서버] 클라이언트 종료: IP 주소=%s, 포트 번호=%d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); }

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

21 connect() 함수 서버에게 접속하여 TCP 프로토콜 수준의 연결 설정 TCP 클라이언트 함수 (2/3)
int connect ( SOCKET s, const struct sockaddr* name, int namelen ) ; 성공: 0, 실패: SOCKET_ERROR

22 connect() 함수 사용 예 TCP 클라이언트 함수 (3/3) 070 SOCKADDR_IN serveraddr;
serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(9000); serveraddr.sin_addr.s_addr = inet_addr(" "); retval = connect(sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr)); if(retval == SOCKET_ERROR) err_quit("connect()");

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

24 데이터 전송 함수 (2/10) send() 함수 애플리케이션 데이터를 송신 버퍼에 복사함으로써 궁극적으로 하부 프로토콜(예를 들면, TCP/IP)에 의해 데이터가 전송되도록 함 int send ( SOCKET s, const char* buf, int len, int flags ); 성공: 보낸 바이트 수, 실패: SOCKET_ERROR

25 recv() 함수 수신 버퍼에 도착한 데이터를 애플리케이션 버퍼로 복사 데이터 전송 함수 (3/10) int recv (
SOCKET s, char* buf, int len, int flags ); 성공: 받은 바이트 수 또는 0(연결 종료시), 실패: SOCKET_ERROR

26 데이터 전송 함수 (4/10) recvn() 함수 037 int recvn(SOCKET s, char *buf, int len, int flags) 038 { int received; char *ptr = buf; int left = len; 042 while(left > 0){ received = recv(s, ptr, left, flags); if(received == SOCKET_ERROR) return SOCKET_ERROR; else if(received == 0) break; left -= received; ptr += received; } 052 return (len - left); 054 }

27 데이터 전송 함수 (5/10) recvn() 함수 동작 원리 buf ptr left len 읽은 데이터

28 데이터 전송 함수 사용 예 – TCP 클라이언트 데이터 전송 함수 (6/10) 078 char buf[BUFSIZE+1];
int len; ... while(1){ // 데이터 입력 ZeroMemory(buf, sizeof(buf)); printf("\n[보낼 데이터] "); if(fgets(buf, BUFSIZE+1, stdin) == NULL) break; 088 // '\n' 문자 제거 len = strlen(buf); if(buf[len-1] == '\n') buf[len-1] = '\0'; if(strlen(buf) == 0) break;

29 데이터 전송 함수 사용 예 – TCP 클라이언트 (cont’d)
데이터 전송 함수 (7/10) 데이터 전송 함수 사용 예 – TCP 클라이언트 (cont’d) // 데이터 보내기 retval = send(sock, buf, strlen(buf), 0); if(retval == SOCKET_ERROR){ err_display("send()"); break; } printf("[TCP 클라이언트] %d바이트를 보냈습니다.\n", retval); 103 // 데이터 받기 retval = recvn(sock, buf, retval, 0); if(retval == SOCKET_ERROR){ err_display("recv()"); break; } else if(retval == 0) break;

30 데이터 전송 함수 사용 예 – TCP 클라이언트 (cont’d)
데이터 전송 함수 (8/10) 데이터 전송 함수 사용 예 – TCP 클라이언트 (cont’d) // 받은 데이터 출력 buf[retval] = '\0'; printf("[TCP 클라이언트] %d바이트를 받았습니다.\n", retval); printf("[받은 데이터] %s\n", buf); }

31 데이터 전송 함수 사용 예 – TCP 서버 데이터 전송 함수 (9/10) 066 char buf[BUFSIZE+1]; ...
while(1){ // 데이터 받기 retval = recv(client_sock, buf, BUFSIZE, 0); if(retval == SOCKET_ERROR){ err_display("recv()"); break; } else if(retval == 0) break; 089 // 받은 데이터 출력 buf[retval] = '\0'; printf("[TCP/%s:%d] %s\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), buf);

32 데이터 전송 함수 사용 예 – TCP 서버 (cont’d)
데이터 전송 함수 (10/10) 데이터 전송 함수 사용 예 – TCP 서버 (cont’d) // 데이터 보내기 retval = send(client_sock, buf, retval, 0); if(retval == SOCKET_ERROR){ err_display("send()"); break; } }

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

34 메시지 정의 ① 메시지 정의 ② 애플리케이션 프로토콜과 메시지 설계 (2/3) 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; // 선 색상 };

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

36 경계 구분 [송신자] [수신자] 메시지 설계시 고려 사항 (1/2) ① 항상 고정 길이 데이터를 보낸다.
② 경계 구분을 위해 특별한 표시(EOR; End Of Record)를 삽입한다. ③ 보낼 데이터 길이를 고정 길이 데이터로 보낸 후, 가변 길이 데이터를 이어서 보낸다. [수신자] ① 항상 고정 길이 데이터를 받는다. ② EOR이 나올 때까지 데이터를 읽은 후 처리한다. ③ 고정 길이 데이터를 읽어 뒤따라올 데이터의 길이를 알아낸다. 이 길이만큼 데이터를 읽어 처리한다.

37 바이트 정렬 멤버 정렬 빅 엔디안 방식으로 통일 구조체(공용체, 클래스 포함) 멤버의 시작 주소에 대한 제약 사항
메시지 설계시 고려 사항 (2/2) 바이트 정렬 빅 엔디안 방식으로 통일 멤버 정렬 구조체(공용체, 클래스 포함) 멤버의 시작 주소에 대한 제약 사항 #pragma pack 컴파일러 명령을 사용


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

Similar presentations


Ads by Google