14장 소켓.

Slides:



Advertisements
Similar presentations
Network Programming:
Advertisements

TCP 서버/클라이언트 동작 원리 - (1) TCP 서버/클라이언트 예 웹 서버 웹 클라이언트 웹 클라이언트
Java Socket 통신 이개혁 정대준.
TCP/IP Network Experimental Programming [IPv6에 의한 통신 실험]
13장 소켓.
Chapter 06. UDP 서버/클라이언트.
TCP/IP Socket Cover Slide 조태문.
TCP/IP 소켓 프로그래밍 - C 버전 중에서
Department of Computer Engineering
네트워크 프로그래밍 Unix Network Programming, 2nd Ed., W. Richard Stevens, Prentice Hall PTR, 한국어 판 Unix Network Programming, Stevens 저, 김치하, 이재용 역, 대영사,
소켓 모델 주소 지정 in_addr_t inet_addr(const char *ip_address) 연결 지향 모델 (TCP)
4장. 소켓 유형과 프로토콜 Network Lab. 이 원 구 1.
TCP/IP Socket Cover Slide 조태문.
Signal & Inter-Process Communication
Chapter 03. 소켓 주소 구조체 다루기.
얇지만 얇지 않은 TCP/IP 소켓 프로그래밍 C 2판
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.
제 12장 I/O멀티플렉싱(Multiplexing)
Using Standard I/O on Sockets
Department of Computer Engineering
Department of Computer Engineering
Department of Computer Engineering
12장 파이프.
인터넷에서의 데이터 흐름 Application Transport Transport Network Link Unix
Socket Address Structure and Byte Ordering Functions
Department of Computer Engineering
Socket Address Structure and Byte Ordering Functions
Homework 6… 12월 2일(금) 11:59pm까지 자신의 이름과 학번을 출력해 주는 유닉스/리눅스 네트워크 소켓 서버 프로그램 과 클라이언트 프로그램 을 작성해 보세요 참고 (실습1) Hello 프로그램 helloserver.c helloclient.c 컴파일.
Internet Address Conversion Functions
7장. UDP 서버-클라이언트 UDP 서버-클라이언트의 기본 구조와 동작 원리를 이해한다.
Chapter 8 연결형 프로토콜 서버 발표자 : SE Lab 황 성 하
Department of Computer Engineering
6장 파일 및 레코드 잠금.
Department of Computer Engineering
Department of Computer Science and Engineering
Chapter 03. 소켓 주소 구조체 다루기.
Socket Address Structure and Byte Ordering Functions
Internet Address Conversion Functions
Socket Address Structure and Byte Ordering Functions
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
7장. UDP 서버-클라이언트 UDP 서버-클라이언트의 기본 구조와 동작 원리를 이해한다.
Signal & Inter-Process Communication
Internet Address Conversion Functions
(분산 통신 실습) : 소켓(Sockets)
School of Electronics and Information. Kyung Hee University.
네트워크 프로그래밍의 이해 School of Electronics and Information.
윤성우의 열혈 TCP/IP 소켓 프로그래밍 윤성우 저 열혈강의 TCP/IP 소켓 프로그래밍 개정판
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Chapter 16 Socket Interface.
Department of Computer Engineering
조 병 규 Software Quality Lab. 한국교통대학교
Department of Computer Engineering
인터넷 주소변환 School of Electronics and Information. Kyung Hee University.
Chapter 04. TCP 서버/클라이언트.
인공지능실험실 박사 1학기 장성만 TCP/IP Socket Programming… 제 8장 도메인 이름과 인터네 주소 인공지능실험실 박사 1학기 장성만
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
Chapter 03. 소켓 주소 구조체 다루기.
소켓의 생성과 프로토콜의 설정 School of Electronics and Information.
Signal & Inter-Process Communication
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
Department of Computer Engineering
Presentation transcript:

14장 소켓

14.1 소켓

클라이언트-서버 모델 네트워크 응용 프로그램 클라이언트-서버 모델 클리이언트-서버 모델을 기반으로 동작한다 하나의 서버 프로세스와 여러 개의 클라이언트로 구성된다 서버는 어떤 자원을 관리하고 클라이언트를 위해 자원 관련 서 비스를 제공한다

소켓의 종류 소켓 유닉스 소켓(AF_UNIX) 인터넷 소켓(AF_INET) 네트워크에 대한 사용자 수준의 인터페이스를 제공 소켓은 양방향 통신 방법으로 클라이언트-서버 모델을 기반으로 프로세스 사이의 통신에 매우 적합하다 유닉스 소켓(AF_UNIX) 같은 호스트 내의 프로세스 사이의 통신 방법 인터넷 소켓(AF_INET) 인터넷에 연결된 서로 다른 호스트에 있는 프로세스 사이의 통 신 방법

소켓 연결 1. 서버가 소켓을 만든다 2. 클라이언트가 소켓을 만든 후 서버에 연결 요청을 한다 3. 서버가 클라이언트의 연결 요청을 수락하여 소켓 연결이 이루어진다

소켓 연결 과정 서버 클라이언트 1. socket() 호출을 이용하여 소켓을 만들고 이름을 붙인다 2. listen() 호출을 이용하여 대기 큐를 만든다 3. 클라이언트로부터 연결 요청을 accept() 호출을 이용하여 수락한다 4. 소켓 연결이 이루어지면 - 자식 프로세스를 생성하여 - 클라이언트로부터 요청 처리 - 클라이언트에게 응답한다 클라이언트 1. socket() 호출을 이용하여 소켓 을 만든다 2. connection() 호출을 이용하여 서버에 연결 요청을 한다 3. 서버가 연결 요청을 수락하면 소켓 연결이 만들어진다 4. 서버에 서비스를 요청하고 서버 로부터 응답을 받아 처리한다

소켓 연결 과정

소켓 만들기 인터넷 소켓 fd = socket(AF_INET, SOCK_STREAM, DEFAULT _PROTOCOL); 유닉스 소켓 fd = socket(AF_UNIX, SOCK_STREAM, DEFAULT _PROTOCOL); int socket(int domain, int type, int protocol) 소켓을 생성하고 소켓을 위한 파일 디스크립터를 리턴, 실패하면 -1을 리턴한다.

소켓에 이름(주소) 주기 유닉스 소켓 이름 인터넷 소켓 이름 struct sockaddr_un { unsigned short sun_family; // AF_UNIX char sun_path[108]; // 소켓 이름 } 인터넷 소켓 이름 struct sockaddr_in { unsigned short sin_family; // AF_INET unsigned short sin_port; // 인터넷 소켓의 포트 번호 struct in_addr sin_addr; // 32-bit IP 주소 char sin_zero[8]; // 사용 안 함 int bind(int fd, struct sockaddr* address, int addressLen) 소켓에 대한 이름 바인딩이 성공하면 0을 실패하면 -1을 리턴한다.

소켓 큐 생성 listen() 시스템 호출 listen(serverFd, 5); 클라이언트로부터의 연결 요청을 기다린다. 연결 요청 대기 큐의 길이를 정한다. listen(serverFd, 5); int listen(int fd, int queueLength) 소켓 fd에 대한 연결 요청을 기다린다. 성공하면 0을 실패하면 -1을 리턴한다.

소켓에 연결 요청 connect() 시스템 호출 fd가 나타내는 클라이언트 소켓과 address가 나타내는 서버 소 켓과의 연결을 요청한다. 성공하면 fd를 서버 소켓과의 통신에 사용할 수 있다. int connect(int fd, struct sockaddr* address, int addressLen) 성공하면 0을 실패하면 -1를 리턴한다.

연결 요청 수락 서버가 클라이언트로부터의 연결요청을 수락하는 내부 과정 1. 서버는 fd가 나타내는 서버 소켓을 경청하고 2. 클라이언트의 연결 요청이 올 때까지 기다린다. 3. 클라이언트로부터 연결 요청이 오면 원래 서버 소켓과 같은 복사본 소켓을 만들어 이 복사본 소켓과 클라이언트 소켓을 연결 4. 연결이 이루어지면 address는 클라이언트 소켓의 주소로 세팅되고 addressLen는 그 크기로 세팅 5. 새로 만들어진 복사본 소켓의 파일 디스크립터를 리턴 int accept(int fd, struct sockaddr* address, int* addressLen) 성공하면 새로 만들어진 복사본 소켓의 파일 디스크립터, 실패하면 -1을 리턴한다.

대문자 변환 서버 이 프로그램 서버 클라이언트 입력받은 문자열을 소문자를 대문자로 변환한다 서버와 클라이언트로 구성된다 소켓을 통해 클라이언트로부터 받은 문자열을 소문자를 대문자 로 변환하여 소켓을 통해 클라이언트에 다시 보낸다 클라이언트 표준입력으로부터 문자열을 입력받아 이를 소켓을 통해 서버에 보낸 후에 대문자로 변환된 문자열을 다시 받아 표준출력에 출력한다

cserver.c #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define DEFAULT_PROTOCOL 0 #define MAXLINE 100 /* 소문자를 대문자로 변환하는 서버 프로그램 */ int main () { int listenfd, connfd, clientlen; char inmsg[MAXLINE], outmsg[MAXLINE]; struct sockaddr_un serverUNIXaddr, clientUNIXaddr; signal(SIGCHLD, SIG_IGN); clientlen = sizeof(clientUNIXaddr); listenfd = socket(AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL); serverUNIXaddr.sun_family = AF_UNIX; unlink("convert"); bind(listenfd, (const struct sockaddr *)&serverUNIXaddr, sizeof(serverUNIXaddr)); listen(listenfd, 5);

cserver.c while (1) { /* 소켓 연결 요청 수락 */ connfd = accept(listenfd, (struct sockaddr *)&clientUNIXaddr, &clientlen); if (fork ( ) == 0) { /* 소켓으로부터 한 줄을 읽어 대문자로 변환하여 보냄 */ readLine(connfd, inmsg); toUpper(inmsg, outmsg); write(connfd, outmsg, strlen(outmsg)+1); close(connfd); exit (0); } else close(connfd); } /* 소문자를 대문자로 변환 */ toUpper(char* in, char* out) { int i; for (i = 0; i < strlen(in); i++) if (islower(in[i])) out[i] = toupper(in[i]); else out[i] = in[i]; out[i] = (int)NULL; } /* 한 줄 읽기 */ readLine(int fd, char* str) int n; do { n = read(fd, str, 1); } while(n > 0 && *str++ != (int)NULL); return(n > 0);

cclient.c #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define DEFAULT_PROTOCOL 0 #define MAXLINE 100 /* 소문자-대문자 변환: 클라이언트 프로그램 */ int main ( ) { int clientfd, result; char inmsg[MAXLINE], outmsg[MAXLINE]; struct sockaddr_un serverUNIXaddr; clientfd = socket(AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL); serverUNIXaddr.sun_family = AF_UNIX; strcpy(serverUNIXaddr.sun_path, "convert"); do { /* 연결 요청 */ result = connect(clientfd, &serverUNIXaddr, sizeof(serverUNIXaddr)); if (result == -1) sleep(1); } while (result == -1);

cclient.c printf("변환할 문자열 입력:\n"); fgets(inmsg, MAXLINE, stdin); write(clientfd,inmsg,strlen(inmsg)+1); // 변환할 문자열 보내기 /* 소켓으로부터 변환된 문자열을 한 줄 읽어서 프린트 */ readLine(clientfd,outmsg); printf("%s --> \n%s", inmsg, outmsg); close(clientfd); exit(0); } /* 한 줄 읽기 */ readLine(int fd, char* str) { int n; do { n = read(fd, str, 1); } while(n > 0 && *str++ != (int)NULL); return(n > 0);

14.2 인터넷 소켓

인터넷 상의 호스트 인터넷 상의 호스트는 32 비트 IP 주소를 갖는다 IP 주소는 대응하는 도메인 이름을 갖는다. 예: 117.16.191.4 IP 주소는 대응하는 도메인 이름을 갖는다. 예: 117.16.191.4 --> www.incheon.ac.kr 32 비트 IP 주소는 저장 /* 인터넷 주소 구조체 */ struct in_addr { unsigned int s_addr; // 네트워크 바이트 순서(big-endian) };

DNS(Domain Name System) 인터넷은 IP 주소와 도메인 이름 사이의 맵핑을 DNS라 부르 는 전세계적인 분산 데이터베이스에 유지한다 /* DNS 호스트 엔트리 구조체 */ struct hostent { char *h_name; // 호스트의 공식 도메인 이름 char **h_aliases; // null로 끝나는 도메인 이름의 배열 int h_addrtype; // 호스트 주소 타입(AF_INET) int h_length; // 주소의 길이 char **h_addr_list; // null로 끝나는 in_addr 구조체의 배열 };

DNS 관련 함수 호스트의 주소 혹은 이름을 이용하여 DNS로부터 호스트 엔 트리를 검색할 수 있다 struct hostent *gethostbyaddr(const char* addr, int len, int type); 길이가 len이고 주소 타입 type인 호스트 주소 addr에 해당하는 hostent 구조체를 리턴한다. struct hostent* gethostbyname(char* name); 도메인 이름에 대응하는 hostent 구조체에 대한 포인터를 리턴한다.

DNS 관련 함수 in_addr 구조체 형식으로 된 IP 주소를 프린트 할 수 있는 스트링으로 변환한다 char* inet_ntoa(struct in_addr address); IP 주소 address에 대응하는 A.B.C.D 포맷의 스트링을 리턴한다. unsigned long inet_addr(char* string); A.B.C.D 포맷의 IP 주소를 네트워크 바이트 순서로 된 이진 데이터로 변환하여 리턴한다.

인터넷 소켓 인터넷 소켓 인터넷 소켓 연결 예 서로 다른 호스트에서 실행되는 클라이언트-서버 사이의 통신 양방향(2-way) 통신 소켓을 식별하기 위해 호스트의 IP 주소와 포트 번호를 사용 인터넷 소켓 연결 예

인터넷 소켓 인터넷 소켓 통신을 사용하는 SW 잘 알려진 서비스의 포트 번호 웹 브라우저 ftp telnet ssh 시간 서버: 13번 포트 ftp 서버: 20,21번 포트 텔넷 서버: 23번 포트 메일 서버: 25번 포트 웹 서버: 80번 포트

클라이언트-서버 인터넷 소켓 연결 과정

인터넷 소켓 이름(주소) 인터넷 소켓 이름(주소) 소켓 이름을 위한 포괄적 구조체 struct sockaddr_in { unsigned short sin_family; // AF_INET unsigned short sin_port; // 인터넷 소켓의 포트 번호 struct in_addr sin_addr; // 32-bit IP 주소 char sin_zero[8]; // 사용 안 함 } 소켓 이름을 위한 포괄적 구조체 struct sockaddr { unsigned short sa_family; // 프로토콜 패밀리 char sa_data[14]; // 주소 데이터 };

파일 서버-클라이언트 서버 클라이언트 파일 이름을 받아 해당 파일을 찾아 그 내용을 보내주는 서비스 명령줄 인수로 포트 번호를 받아 해당 소켓을 만든다 이 소켓을 통해 클라이언트로부터 파일 이름을 받아 해당 파일을 열고 그 내용을 이 소켓을 통해 클라이언트에게 보 낸다 클라이언트 명령줄 인수로 연결할 서버의 이름과 포트 번호를 받아 해당 서 버에 소켓 연결을 한다 이 연결을 통해 서버에 원하는 파일 이름을 보낸 후 서버로부터 해당 파일 내용을 받아 사용자에게 출력한다

fserver.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #define DEFAULT_PROTOCOL 0 #define MAXLINE 100 /* 파일 서버 프로그램 */ int main (int argc, char* argv[]) { int listenfd, connfd, port, clientlen; FILE *fp; char inmsg[MAXLINE], outmsg[MAXLINE]; struct sockaddr_in serveraddr, clientaddr; struct hostent *hp; char *haddrp; signal(SIGCHLD, SIG_IGN); if (argc != 2) { fprintf(stderr, "사용법: %s <port>\n", argv[0]); exit(0); } port = atoi(argv[1]); listenfd = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL); bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons((unsigned short)port); bind(listenfd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr)); listen(listenfd, 5);

fserver.c while (1) { clientlen = sizeof(clientaddr); connfd = accept(listenfd, (struct sockaddr *)&clientaddr, &clientlen); /* 클라이언트의 도메인 이름과 IP 주소 결정 */ hp = gethostbyaddr((char *)&clientaddr.sin_addr.s_addr, sizeof(clientaddr.sin_addr.s_addr), AF_INET); haddrp = inet_ntoa(clientaddr.sin_addr); printf("클라이언트: %s 포트: %d 연결됨\n", haddrp, clientaddr.sin_port); if (fork () == 0) { readLine(connfd, inmsg); /* 소켓에서 파일 이름을 읽는다 */ fp = fopen(inmsg, "r"); if (fp == NULL) { write(connfd, "해당 파일 없음", 10); } else { /* 파일에서 한 줄씩 읽어 소켓을 통해 보낸다 */ while(fgets(outmsg, MAXLINE, fp) != NULL) write(connfd, outmsg, strlen(outmsg)+1); } close(connfd); exit (0); } else close(connfd); } // while } // main readLine(int fd, char* str) { int n; do { n = read(fd, str, 1); } while(n > 0 && *str++ != (int)NULL); return(n > 0);

fclient.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #define DEFAULT_PROTOCOL 0 #define MAXLINE 100 /* 파일 클라이언트 프로그램 */ int main (int argc, char* argv[]) { int clientFd, port, result; char *host, inmsg[MAXLINE], outmsg[MAXLINE]; struct sockaddr_in serverAddr; struct hostent *hp; struct in_addr *hostnode; char *hostaddress; if (argc != 3) { fprintf(stderr, "사용법 : %s <host> <port>\n", argv[0]); exit(0); } host = argv[1]; port = atoi(argv[2]); clientFd = socket(AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL); /* 서버의 IP 주소와 포트 번호를 채운다 */ if ((hp = gethostbyname(host)) == NULL) perror("gethostbyname error"); // 호스트 찾기 오류 hostnode = (struct in_addr *)hp->h_addr; hostaddress = inet_ntoa(*hostnode); printf("서버: %s 포트: %d 연결 요청\n", hostaddress, port);

fclient.c bzero((struct sockaddr *)&serverAddr, sizeof(serverAddr)); serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = hostnode->s_addr; serverAddr.sin_port = htons(port); do { /* 연결 요청 */ result = connect(clientFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); if (result == -1) sleep(1); } while (result == -1); sleep(1); // 서버 메시지 출력 후 입력 유도 printf("파일 이름 입력: "); scanf("%s", inmsg); write(clientFd,inmsg,strlen(inmsg)+1); /* 소켓으로부터 파일 내용 읽어서 프린트 */ while (readLine(clientFd, outmsg)) printf("%s", outmsg); close(clientFd); exit(0); } readLine(int fd, char* str) { int n; do { n = read(fd, str, 1); } while(n > 0 && *str++ != (int)NULL); return(n > 0);

핵심 개념 소켓은 양방향 통신 방법으로 클라이언트-서버 모델을 기반으로 프로세스 사이의 통신에 매우 적합하다 소켓은 양방향 통신 방법으로 클라이언트-서버 모델을 기반으로 프로세스 사이의 통신에 매우 적합하다 소켓에는 같은 호스트 내의 프로세스 사이의 통신을 위한 유닉스 소켓과 다른 호스트에 있는 프로세스 사이의 통신을 위한 인터넷 소켓이 있다