linux socket programming - introducing sockets –

78
한한한한한 한한한한한한 한한한 한한한한 한한한 1 Linux Socket Programming Linux Socket Programming - Introducing Sockets – - Introducing Sockets – Network Lab. 한 한 한

Upload: ursala

Post on 17-Mar-2016

79 views

Category:

Documents


3 download

DESCRIPTION

Linux Socket Programming - Introducing Sockets –. Network Lab. 이 성 현. 목 차. 소켓의 역사 소켓의 본질 리눅스 커널과 응용 프로그램의 소켓 참조 소켓 C 프로그램 예제. 간단한 역사 소개. 1957. 10. 04 - Sputnik 발사 성공 1958. 01. 07 - ARPA(Advanced Research Projects Agency) 출범 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Linux Socket Programming - Introducing Sockets  –

한남대학교 컴퓨터공학과 컴퓨터 네 트워크 실험실 1

Linux Socket ProgrammingLinux Socket Programming- Introducing Sockets –- Introducing Sockets –

Network Lab.이 성 현

Page 2: Linux Socket Programming - Introducing Sockets  –

2HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

목 차목 차

소켓의 역사

소켓의 본질

리눅스 커널과 응용 프로그램의 소켓 참조

소켓 C 프로그램 예제

Page 3: Linux Socket Programming - Introducing Sockets  –

3HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

간단한 역사 소개간단한 역사 소개 1957. 10. 04 - Sputnik 발사 성공

1958. 01. 07 - ARPA(Advanced Research Projects Agency) 출범

1962 - J.C.R Licklider : 서로 다른 컴퓨터 간의 통신을 위 한 아이디어 창출

1969 - ARPA & UNIX

1982 - 4.1BSD 와 4.2BSD 에 TCP/IP 를 포함한 UCB 배포

1991. 10. 05 – Linux 0.02 발표

Page 4: Linux Socket Programming - Introducing Sockets  –

4HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

간단한 역사 소개간단한 역사 소개 (( 계속계속 ))SputnikARPA

J.C.R Licklider

UNIX

DARPA funds UCB4.1BSD and 4.2BSD

Linux 0.02

October 4, 1957January 1, 1958

1962

1969

1979

1982

October 5, 1991

ARPANET

Soc ket s

그림 1.1: ARPA 으로부터 24 년 후에 BSD 소켓 발달

Page 5: Linux Socket Programming - Introducing Sockets  –

5HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 소켓의 정의 – 전화 네트워크와의 비교

리눅스의 소켓은 전화와 유사

소켓은 통신라인의 종점을 표시

전화 : 전화번호 – 소켓 : 네트워크 주소

소켓은 통신의 종점이기 때문에 종료 가능

Page 6: Linux Socket Programming - Introducing Sockets  –

6HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 ))

전화 네트워크

Telephone

Network

그림 1.2 전화 네트워크

Page 7: Linux Socket Programming - Introducing Sockets  –

7HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓에 대한 이해소켓에 대한 이해 (( 계속계속 )) 소켓의 정의

소켓은 소프트웨어로 작성된 통신 접속점

소켓은 서버와 서로 특정한 규약을 사용하여 데이터를 전송하는 방식

네트워크 응용 프로그램은 소켓을 통해 데이터 송수신

소켓 인터페이스 - 응용 프로그램에서 TCP/IP 를 이용하는 창구 역할을 하는 인터페이스

Page 8: Linux Socket Programming - Introducing Sockets  –

8HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 ))

네트워크 드라이버TCP/IP

응용 1 응용 2 응용 3

소켓 2소켓 1 소켓 3소켓 인터페이스

네트워크1

2

3

4

5-7

(OSI 계층 )

그림 1.3: 소켓 인터페이스 위치

Page 9: Linux Socket Programming - Introducing Sockets  –

9HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 )) 소켓 사용

open(2) 함수를 사용하여 파일을 열 때 , 파일 기술자를 리턴하면 성공

read(2), write(2), lseek(2), close(2) 를 사용하여 파일을 열 수 있다 .

Page 10: Linux Socket Programming - Introducing Sockets  –

10HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 )) 소켓과 파이프의 차이점

소켓은 lseek(2) 할 수 없다 . 소켓은 위치 주소를 가지지만 , 파일과 파이프는 네트워크

주소를 가질 수 없다 . 소켓은 서로 다른 옵션을 사용할 수 있으며 , 소켓에 대한

질문과 ioctl(2) 를 사용할 수 있다 . 소켓은 입 / 출력을 위해 올바른 상태를 가져야 하지만 ,

오픈된 파일은 어떠한 때라도 읽거나 쓸 수 있다 .

Page 11: Linux Socket Programming - Introducing Sockets  –

11HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 )) 소켓 참조

open(2) 함수를 호출하여 새로운 파일을 열었을 때 , 파일 기술자를 리눅스 커널에서 리턴

파일 기술자를 호출하여 , 파일이 열려질 때 0 또는 양의 정수 값을 이용

Page 12: Linux Socket Programming - Introducing Sockets  –

12HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 )) 파일 기술자가 커널에 위치하는 과정

1. 파일을 열기 위해서 open(2) 함수 호출

2. 파일 기술자 3 이 열려진 파일을 참조하기위해서 리턴된다 .

3. 새로운 소켓이 적당한 함수를 호출하여 생성된다 .

4. 파일 기술자 4 는 새로운 소켓을 참조하기 위해서 리턴된다 .

5. 다른 파일이 open(2) 를 호출하여 열린다 .

6. 파일 기술자 5 는 새로 오픈된 파일을 참조하기 위해서 리턴된다 .

Page 13: Linux Socket Programming - Introducing Sockets  –

13HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 ))

bind()

listen()

accept()

write()

read()

read()

connect()

socket()

write()

close()

데이터데이터

연결요청

종료

서버 클라이언트socket()

그림 1.4: 소켓 연결 개요

Page 14: Linux Socket Programming - Introducing Sockets  –

14HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 )) 소켓 함수의 예

socket() : 사용하고자 하는 통신 프로토콜을 지정 int socket(int domain, int type, int protocol);

socketpair() : 소켓 연결의 한 쌍을 지정 int socketpair(int domain, int type, int protocol, int sv[2]);

bind() : 소켓에 이름을 결합 int bind(int sockfd, sockaddr * myaddr, int addrlen);

Page 15: Linux Socket Programming - Introducing Sockets  –

15HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 )) 소켓 함수의 예

connect() : 클라이언트가 서버에 연결을 요청하기 위해 호출 int connect(int socfd, struct sockaddr *servaddr, int addrlen);

listen() : 서버 프로세스가 통신할 연결기반 소켓 설정 int listen(int sockfd, int size);

accept() : 서버 프로세스에서 클라이언트 소켓과 연결을 설정 하기 위해 호출

int accept(int sockfd, struct sockaddr *peer, int *addrlen);

Page 16: Linux Socket Programming - Introducing Sockets  –

16HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 이해소켓의 이해 (( 계속계속 )) 소켓 함수의 예

write() : 다른 소켓에 메시지 전송 ssize_t write(int fd, const void *buf, size_t count);

read() : 다른 소켓에서 메시지 수신 ssize_t read(int fd, void *buf, size_t count);

close() : 소켓의 연결을 종료 int close(int fd);

Page 17: Linux Socket Programming - Introducing Sockets  –

17HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓과 파이프의 비교소켓과 파이프의 비교 pipe

pipe(2) 함수 호출이 성공이면 , 두개의 파일 기술자가 리턴된다 .

filedes[0] : 파이프의 끝까지 읽기 위해서 파일 기술자를

담는다 .

filedes[1] : 파이프의 끝까지 쓰기 위해서 파일 기술자를 받는다 .

오직 하나의 직접적인 통신 라인 생성

Page 18: Linux Socket Programming - Introducing Sockets  –

18HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓과 파이프의 비교소켓과 파이프의 비교 (( 계속계속 )) 소켓

직접적인 통신 프로세스만 허용

프로세스는 소켓을 열기 위해 파일 기술자 3 사용

지역 프로세스가 파일 기술자 3 으로부터 정보를 받아 통신이 이루어지는 원격 프로세스에 보낼 수 있다 .

Page 19: Linux Socket Programming - Introducing Sockets  –

19HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 Socketpair(2) 함수

int socketpair(int domain, int type, int protocol, int sv[2]);

소켓의 도메인

소켓의 형태

소켓이 사용하는 프로토콜

소켓을 생성하고 참조하는 파일 기술자를 받기 위한 배열 포인터

Page 20: Linux Socket Programming - Introducing Sockets  –

20HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) type 인수 – 소켓의 타입 선언

SOCK_STREAM 스트림 소켓

SOCK_DGRAM 데이터그램 소켓

Page 21: Linux Socket Programming - Introducing Sockets  –

21HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) socketpair(2) 리턴 값

success : 0

error : -1, errno 에 에러 발생 이유 출력

Page 22: Linux Socket Programming - Introducing Sockets  –

22HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) socketpair(2) 예제 – Listing 1.1

13: int 14: main(int argc,char **argv) { 15: int z; /* Status return cod

e */ 16: int s[2]; /* Pair of sockets *

/

16 라인에서 소켓이 생성되고 참조되는 두 개의 새로운 파일 기술자를 s[2] 의 배열로 받음

Page 23: Linux Socket Programming - Introducing Sockets  –

23HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) socketpair(2) 예제 – Listing 1.1

21: z = socketpair(AF_LOCAL,SOCK_STREAM,0,s);

socketpair(2) 함수 호출 AF_LOCAL : 도메인 인수 지정 SOCK_STREAM : 소켓 타입 0 : 프로토콜 0 으로 지정 s : 파일 기술자를 받기 위한 배열 포인터 지정

Page 24: Linux Socket Programming - Introducing Sockets  –

24HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) socketpair(2) 예제 – Listing 1.1

23: if ( z == -1 ) { 24: fprintf(stderr, 25: "%s:

socketpair(AF_LOCAL,SOCK_STREAM,0)\n",

26: strerror(errno)); 27: return 1; /* Failed */

에러 발생 출력

Page 25: Linux Socket Programming - Introducing Sockets  –

25HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) socketpair(2) 예제 – Listing 1.1

33: printf("s[0] = %d;\n",s[0]); 34: printf("s[1] = %d;\n",s[1]);

소켓 s[0] 의 파일 기술자 출력

소켓 s[1] 의 파일 기술자 출력

Page 26: Linux Socket Programming - Introducing Sockets  –

26HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) socketpair(2) 예제 – Listing 1.1

36: system("netstat --unix -p");

netstat(1) 명령어는 system(3) 함수를 사용 --unix : AF_LOCAL 도메인을 출력 -p : 프로세스의 정보를 출력

Page 27: Linux Socket Programming - Introducing Sockets  –

27HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) 실행 결과

1: $ ./01lst01 2: s[0] = 3; 3: s[1] = 4; 4: (Not all processes could be identified, non-owned process info 5: will not be shown, you would have to be root to see it all.) 6: Active UNIX domain sockets (w/o servers) 7: Proto RefCnt Flags Type State I-Node PID/Program name Path 8: unix 1 [ ] STREAM CONNECTED 112354 - @0000022

c 9: unix 1 [ ] STREAM CONNECTED 112220 - @0000020

e 10: unix 12 [ ] DGRAM 485 - /dev/log 11: unix 1 [ ] STREAM CONNECTED 112286 - @0000021

8………………………

21: unix 1 [ ] STREAM CONNECTED 288195 28402/01lst01 22: unix 1 [ ] STREAM CONNECTED 288194 28402/01lst01

………………………

Page 28: Linux Socket Programming - Introducing Sockets  –

28HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 생성소켓의 생성 (( 계속계속 )) 실행 결과 분석

2-3 라인 : 파일 기술자 3, 4 에 의해 열려진 소켓

2-45 라인 : netstat(1) 명령으로 system(3) 함수를 호 출하여 출력

21-22 라인 : 소켓의 정보 출력 프로그램 명 : 01lst01 프로세스 ID : 28402

Page 29: Linux Socket Programming - Introducing Sockets  –

29HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 read(2), write(2), close(2) 함수 호출

#include <unistd.h> ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); int close(int fd);

read(2) : 파일 기술자의 이용 가능한 값을 count 바 이트에 정의된 값 만큼 buf 에 할당 리턴값 : 읽은 바이트 숫자

Page 30: Linux Socket Programming - Introducing Sockets  –

30HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) read(2), write(2), close(2) 함수 호출

write(2) : 버퍼 buf 를 제공받은 파일 기술자 fd 로부 터 데이터를 작성 리턴 값 : 작성중인 바이트 숫자 , 일반적으로 count

인수 값 과 일치

close(2) : 파일 기술자가 성공적으로 종료되었을 때 0 을 리턴

Page 31: Linux Socket Programming - Introducing Sockets  –

31HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

16: int s[2]; /* Pair of sockets */………………….

23: z = socketpair(AF_LOCAL,SOCK_STREAM,0,s);

socketpair(2) 함수가 23 라인에서 호출되고 , 성공적으로 이루어 졌다면 , s[2] 배열의 s[0] 와 s[1] 에 파일 기술자 리턴

Page 32: Linux Socket Programming - Introducing Sockets  –

32HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

25: if ( z == -1 ) { 26: fprintf(stderr, 27: "%s: socketpair(AF_LOCAL,SOCK_STREAM," 28: "0)\n", 29: strerror(errno)); 30: return 1;

에러 발생 출력

Page 33: Linux Socket Programming - Introducing Sockets  –

33HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

36: z = write(s[1],cp="Hello?",6);

“Hello?” 메시지가 소켓 s[1] 에 작성 , write(2) 함수의 count 인수에 6 으로 할당된 버퍼 값 때문에 공백 바이트를 작성하지 않는다 .

Page 34: Linux Socket Programming - Introducing Sockets  –

34HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

37: if ( z < 0 ) { 38: fprintf(stderr, 39: "%s: write(%d,\"%s\",%d)\n", 40: strerror(errno),s[1],cp,strlen(cp)); 41: return 2; /* Failed write */

에러 발생 출력

Page 35: Linux Socket Programming - Introducing Sockets  –

35HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

44: printf("Wrote message '%s' on s[1]\n",cp);

s[1] 의 메시지 출력

49: z = read(s[0],buf,sizeof buf);

소켓 s[0] 의 메시지를 읽어 버퍼에 저장

Page 36: Linux Socket Programming - Introducing Sockets  –

36HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

50: if ( z < 0 ) { 51: fprintf(stderr, 52: "%s: read(%d,buf,%d)\n", 53: strerror(errno),s[0],sizeof buf); 54: return 3; /* Failed read */

에러 발생 출력

Page 37: Linux Socket Programming - Introducing Sockets  –

37HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

60: buf[z] = 0; /* NUL terminate */ 61: printf("Received message '%s' from s

ocket s[0]\n", 62: buf);

소켓이 성공적으로 메시지를 받았다는 것을 출력

Page 38: Linux Socket Programming - Introducing Sockets  –

38HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

67: z = write(s[0],cp="Go away!",8); 68: if ( z < 0 ) { 69: fprintf(stderr, 70: "%s: write(%d,\"%s\",%d)\n", 71: strerror(errno),s[0],cp,strlen(cp)); 72: return 4; /* Failed write */

소켓 s[0] 에 “ Go away!” 메시지를 저장

에러 발생 출력

Page 39: Linux Socket Programming - Introducing Sockets  –

39HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

75: printf("Wrote message '%s' on s[0]\n",cp);

s[0] 의 메시지 출력

Page 40: Linux Socket Programming - Introducing Sockets  –

40HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

80: z = read(s[1],buf,sizeof buf); 81: if ( z < 0 ) { 82: fprintf(stderr, 83: "%s: read(%d,buf,%d)\n", 84: strerror(errno),s[1],sizeof buf); 85: return 3; /* Failed read */

소켓 s[1] 의 메시지를 읽어 버퍼에 저장

에러 발생 출력

Page 41: Linux Socket Programming - Introducing Sockets  –

41HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

91: buf[z] = 0; /* NUL terminate */ 92: printf("Received message '%s' from s

ocket s[1]\n", 93: buf);

메시지의 수신이 성공

소켓 s[1] 으로부터 받은 메시지 출력

Page 42: Linux Socket Programming - Introducing Sockets  –

42HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 예제 프로그램 -Listing 1.2

98: close(s[0]); 99: close(s[1]);

소켓 s[0] 와 s[1] 을 종료 102: return 0;

프로그램을 종료

Page 43: Linux Socket Programming - Introducing Sockets  –

43HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 입출력 실행소켓의 입출력 실행 (( 계속계속 )) 실행 결과

$ ./01lst02 Wrote message 'Hello?' on s[1] Received message 'Hello?' from socket s[0] Wrote message 'Go away!' on s[0] Received message 'Go away!' from socket s[1] Done.

Page 44: Linux Socket Programming - Introducing Sockets  –

44HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 close(2) 함수

소켓 종료시에 사용

소켓이 종료되면 , 원격 소켓으로부터 데이터 받을 수 없음 .

한 쌍의 소켓에서 하나만 종료된 것을 의미

Page 45: Linux Socket Programming - Introducing Sockets  –

45HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 (( 계속계속 )) shutdown(2) 함수

#include shutdown(int s, int how);

shutdown 함수는 두 개의 인수를 요구 명시한 함수를 부분적으로 shutdown 시키기 위한 소켓

기술자 s 소켓을 shutdown 시키는 방법을 가리키는 how 인수

리턴값 함수 호출 성공 : 0 함수 호출 실패 : -1

Page 46: Linux Socket Programming - Introducing Sockets  –

46HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 (( 계속계속 )) how 인수가 허용하는 값

값 매크로 기술

0 SHUT_RD 명시한 소켓에서 읽는 것을 허용하지 않는다 .

1 SHUT_WR 명시한 소켓에 쓰는 것을 허용하지 않는다 .

2 SHUT_RDWR 명시한 소켓에서 읽거나 쓰는 것을 허용하지 않는다 .

테이블 1.1: shutdown(2) 함수의 how 인수 허용 값

Page 47: Linux Socket Programming - Introducing Sockets  –

47HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 (( 계속계속 )) 소켓 쓰기 shutdown

쓰기를 허용하지 않는 예제

int z; int s; /*Socket */

z = shutdown(s, SHUT_WR); if ( z == -1 ) perror("shutdown()");

Page 48: Linux Socket Programming - Introducing Sockets  –

48HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 (( 계속계속 )) 소켓 쓰기 종료의 문제 해결

커널 네트워킹 소프트웨어에 의해 데이터가 버퍼에 저장된다 .

EOF 지시자를 원격 소켓에 보낸다 . 이것은 원격 일기 프로세스에게 소켓에 더 이상의 데이터가 없음을 알려준다 .

EOF 지시자 이후에 보내는 메시지를 받기 위해 부분적으로 소켓을 열어 놓는다 .

EOF 지시자를 보낸 소켓을 종료한다 .

Page 49: Linux Socket Programming - Introducing Sockets  –

49HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 (( 계속계속 )) 중복 소켓 처리

int s; /* Existion socket */ int d; /* Duplicated socket */

d = dup(s); /* duplicate this socket */ close(s); /* nothing happens yet */ close(d); /* last close, so shutdown socket */

Page 50: Linux Socket Programming - Introducing Sockets  –

50HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 (( 계속계속 )) shutdown() 함수 사용

int s; /* Existing socket */ int d; /* Duplicated socket */

d = dup(s); /* duplicate this socket */ shutdown(s, SHUT_RDWR); /* immediate shutdown */

shutdown() 함수가 소켓 s 를 shutdown

Page 51: Linux Socket Programming - Introducing Sockets  –

51HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 (( 계속계속 )) 소켓 읽기 shutdown

소켓에서 읽어 들이는 것을 종료 수신되지 않은 데이터 무시 원격 소켓이 데이터를 전송하더라도 데이터를 수신하지 않음 에러 발생

Page 52: Linux Socket Programming - Introducing Sockets  –

52HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

소켓의 종료소켓의 종료 (( 계속계속 )) shutdown(2) 함수 에러

shutdown(2) 함수의 에러 테이블에러 기술

EBADF 주어진 소켓에 유효한 파일 기술자가 없다 .

ENOTSOCK 주어진 파일 기술자에 소켓이 없다 .

ENOTCONN 명시된 소켓이 연결되지 않았다 .

테이블 1.2: shutdown(2) 함수의 리턴 에러

Page 53: Linux Socket Programming - Introducing Sockets  –

53HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제 예제

SocketFile Unit

4

SocketFile Unit

3

Kernel

Child Process

Parent Process

그림 1.5: fork(2) 와 socketpair(2) 의 클라이언트 / 서버 예

Page 54: Linux Socket Programming - Introducing Sockets  –

54HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) fork(2) 함수

부모 프로세스PID = 135

자식 프로세스PID = 136

부모 프로세스PID = 135

fork()

fork() 의

리턴값 = 136

fork() 의

리턴값 = 0

그림 1.6: fork(2) 수행 과정

Page 55: Linux Socket Programming - Introducing Sockets  –

55HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 프로세스

socketpair(2) 함수 호출

fork(2) 함수 호출

부모 프로세스와 자식 프로세스로 분기 부모 프로세스 : 서버 프로그램의 역할을 수행 자식 프로세스 : 클라이언트 프로그램의 역할을 수행

Page 56: Linux Socket Programming - Introducing Sockets  –

56HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) strftime(3) 함수

데이터와 시간을 사용하기 위한 문자열 형식

서버 요청된 현재 데이터와 시간을 획득 클라이언트가 요청한 문자열 포맷을 사용하여 리턴

Page 57: Linux Socket Programming - Introducing Sockets  –

57HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) strftime(3) 함수

size_t strftime(char *buf, size_t max, const char *format, const struct tm *tm);

buf : 출력 버퍼 지정

max : 버퍼 사이즈 지정

format : 데이터와 시간의 문자열 형식

tm : 출력 문자열을 생성하는 구성 요소 공급

Page 58: Linux Socket Programming - Introducing Sockets  –

58HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3

19: #ifndef SHUT_WR 20: #define SHUT_RD 0 21: #define SHUT_WR 1 22: #define SHUT_RDWR 2 23: #endif

매크로 상수 값 정의

Page 59: Linux Socket Programming - Introducing Sockets  –

59HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3

40: z = socketpair(AF_LOCAL,SOCK_STREAM,0,s);

socketpair(2) 함수를 호출하여 소켓 생성

42: if ( z == -1 ) { 43: fprintf(stderr,"%s: socketpair(2)\n", 44: strerror(errno)); 45: exit(1);

에러 발생 출력

Page 60: Linux Socket Programming - Introducing Sockets  –

60HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3

51: if ( (chpid = fork()) == (pid_t)-1 ) { ……………………………

56: fprintf(stderr,"%s: fork(2)\n", 57: strerror(errno)); 58: exit(1);

fork(2) 함수를 호출하여 프로세스 분기

에러 발생 출력

Page 61: Linux Socket Programming - Introducing Sockets  –

61HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3

60: } else if ( chpid == 0 ) { 61: 62: /* 63: * This is the child process (client) :

………………………… 125: close(s[1]); /* Close our end now */

자식 프로세스가 클라이언트 프로그램으로 동작

서버에 요청하고 , 응답을 받음

Page 62: Linux Socket Programming - Introducing Sockets  –

62HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3

127: else { 128: 129: /* 130: * This is the parent process (server) : ………………………………. 189: waitpid(chpid,&status,0);

부모 프로세스가 서버 프로그램으로 동작

클라이언트의 요구 수행

Page 63: Linux Socket Programming - Introducing Sockets  –

63HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Server)

136: printf("Child PID is %ld\n",(long)chpid);

137: fflush(stdout);

자식 프로세스의 PID 출력

139: close(s[1]); /* Client uses s[1] */

소켓 s[1] 종료

Page 64: Linux Socket Programming - Introducing Sockets  –

64HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Server)

145: z = read(s[0],buf,sizeof buf); 146: 147: if ( z < 0 ) { 148: fprintf(stderr,"%s: read(2)\n", 149: strerror(errno)); 150: exit(1);

read(2) 함수 호출하여 소켓 s[0] 를 읽음

에러 발생 출력

Page 65: Linux Socket Programming - Introducing Sockets  –

65HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Server)

157: buf[z] = 0;………………………

165: strftime(txbuf,sizeof txbuf, /* Buffer */ 166: buf, /* Input format */ 167: localtime(&td)); /* Input time */

메시지 수신을 종료하면 공백 바이트로 바꿈

버퍼에 저장된 내용을 지정된 포맷으로 변환

Page 66: Linux Socket Programming - Introducing Sockets  –

66HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Server)

163: time(&td); /* Get current time */

현재 시간을 확정

172: z = write(s[0],txbuf,strlen(txbuf)); 173: 174: if ( z < 0 ) { 175: fprintf(stderr,"%s: write(2)\n", 176: strerror(errno)); 177: exit(1);

write(2) 함수를 호출하여 소켓 s[0] 에 메시지 작성

에러 발생 출력

Page 67: Linux Socket Programming - Introducing Sockets  –

67HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Server)

183: close(s[0]);

소켓 s[0] 종료

189: waitpid(chpid,&status,0);

자식 프로세스가 종료할 때까지 부모 프로세스를 종료하지 않기 위해 waitpid(2) 함수 호출

Page 68: Linux Socket Programming - Introducing Sockets  –

68HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Server)

192: return 0;

부모 프로세스 종료

Page 69: Linux Socket Programming - Introducing Sockets  –

69HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Client)

67: printf("Parent PID is %ld\n",(long)getppid());

부모 프로세스 PID 출력

69: close(s[0]); /* Server uses s[1] */

소켓 s[0] 종료

Page 70: Linux Socket Programming - Introducing Sockets  –

70HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Client)

75: msgp = "%A %d-%b-%Y %l:%M %p"; 76: mlen = strlen(msgp);

서버에 보내는 문자열 형식 지정 msgp : 문자열 형식 지정 mlen : 문자열의 길이 지정

Page 71: Linux Socket Programming - Introducing Sockets  –

71HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Client)

78: printf("Child sending request '%s'\n",msgp);

79: fflush(stdout);

서버에 요청하는 문자열 형식 출력

서버에 문자열 전송

Page 72: Linux Socket Programming - Introducing Sockets  –

72HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Client)

84: z = write(s[1],msgp,mlen); 85: 86: if ( z < 0 ) { 87: fprintf(stderr,"%s: write(2)\n", 88: strerror(errno)); 89: exit(1);

write(2) 함수를 호출하여 소켓 s[1] 에 메시지 작성

에러 발생 출력

Page 73: Linux Socket Programming - Introducing Sockets  –

73HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Client)

97: if ( shutdown(s[1],SHUT_WR) == -1 ) {

98: fprintf(stderr,"%s: shutdown(2)\n",

99: strerror(errno)); 100: exit(1);

에러 발생 출력

Page 74: Linux Socket Programming - Introducing Sockets  –

74HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Client)

106: z = read(s[1],rxbuf,sizeof rxbuf); 107: if ( z < 0 ) { 108: fprintf(stderr,"%s: read(2)\n", 109: strerror(errno)); 110: exit(1);

read() 함수를 호출하여 소켓 s[1] 의 응답을 기다림

에러 발생 출력

Page 75: Linux Socket Programming - Introducing Sockets  –

75HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Client)

117: rxbuf[z] = 0;……………………………

122: printf("Server returned '%s'\n",rxbuf); 123: fflush(stdout);

메시지 수신이 종료되면 공백 바이트로 바꿈

응답 메시지 출력

Page 76: Linux Socket Programming - Introducing Sockets  –

76HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) Client/Server 예제 -Listing 1.3(Client)

125: close(s[1]); /* Close our end now */

소켓 s[1] 종료 192: return 0;

클라이언트 프로세스 종료

Page 77: Linux Socket Programming - Introducing Sockets  –

77HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) 실행 결과

$ ./01lst03 Child PID is 28447 Parent PID is 28446 Child sending request '%A %d-%b-%Y %l:%M %p' Server returned 'Tuesday 13-Mar-2001 4:45 PM'

Page 78: Linux Socket Programming - Introducing Sockets  –

78HANNAM UNIVERSITYHttp://netwk.hannam.ac.kr

Client/Server Client/Server 예제예제 (( 계속계속 )) 프로그램 실행 결과 -msgp 변경

75: msgp = "%A %d-%b-%Y %l:%M %p";

75: msgp = "%d-%b-%y";

실행 결과

15-Jul-99