1
2 hello, world 출력 소켓 프로그램의 기능 확장 ① 연결요청 : 서버 프로그램에 연결 요청 (클라이언트 -> 서버) ② print 요청 : 문자열 ‘print’ 전송 (클라이언트 -> 서버) ③ 문자열 전송 : 문자열 ‘hello, world’ 전송 (서버 -> 클라이언트) ④ 화면 출력 : 문자열 ‘hello, world’ 화면 출력 2
3 ☎ ☎ ☎ ☎ 연결요청 “print” ‘p’ ‘r’ ‘i’ ‘n’ ‘t’ \r \n internet shell Hello,world 출력 확장 서버 $ telnet 192.1.2.3 9000 print[enter] 소켓 2156 IP 주소 IP 주소 9000 소켓 internet ☎ ☎ “hello, world” 연결요청 “print” ‘p’ ‘r’ ‘i’ ‘n’ ‘t’ \0 Hello,world 출력 확장 서버 print Hello, world 출력 확장 클라이언트 소켓 2354 IP 주소 IP 주소 9000 소켓 ☎ ☎ internet “hello, world” 3
4 hello, world 출력 소켓 프로그램 확장 / 서버 server rBuffer ‘p’ ⑦ temp 37 while(1) { 38 len = sizeof(c_addr); 39 c_socket = accept(s_socket, (struct sockaddr *) &c_addr, &len); 40 41 length = 0; 42 temp = rBuffer; 43 while((n = read(c_socket, temp, 1)) > 0) { 44 if(*temp == '\r') continue; 45 if(*temp == '\n') break; 46 if(*temp == '\0') break; 47 48 if(length == BUFSIZ) break; 49 temp++; length++; 50 } 51 52 rBuffer[length] = '\0'; 53 54 if(!strcmp(rBuffer, "print") ) { 55 n = strlen(buffer); 56 write(c_socket, buffer, n); 57 } 58 close(c_socket); 59 } 60 close(s_socket); 61 } rBuffer ‘p’ ⑦ temp read(c_socket, temp, 1) client telnet “print” ‘p’ ‘r’ ‘i’ ‘n’ ‘t’ \r \n 응용 프로그램 “print” ‘p’ ‘r’ ‘i’ ‘n’ ‘t’ \0 ① 소켓을 생성 ⑥ 클라이언트 연결 요청 수신 ② 연결 요청을 수신할 주소 설정 ⑦ 클라이언트 요청 서비스 제공 ③ 소켓을 포트에 연결 ⑧ 클라이언트와 연결 종료 ④ 커널(kernel)에 개통 요청 ⑨ 서버 종료 4 ⑤ 무한반복
5 ☎ ☎ 연결요청 “print” ‘p’ ‘r’ ‘i’ ‘n’ ‘t’ \r \n internet “hello, world” shell Hello,world 출력 확장 서버 $ telnet 192.1.2.3 9000 print[enter] 소켓 2156 IP 주소 IP 주소 9000 소켓 ☎ internet ☎ “hello, world” 실행 실행 터미널-1 / 서버측 실행 $ gcc -o hello_ext_server hello_ext_server.c $ hello_ext_server ■ 실행 터미널-2 / 클라이언트측 실행 $ telnet 127.0.0.1 9000 Trying 127.0.0.1... Connected to it (127.0.0.1). Escape character is '^]'. print hello, worldConnection closed by foreign host. $ 5
6 실행 실행 터미널-2 / 클라이언트측 실행 $ telnet 127.0.0.1 9000 Trying 127.0.0.1... Connected to it (127.0.0.1). Escape character is '^]'. print hello, worldConnection closed by foreign host. $ 실행 터미널-1 / 서버측 실행 전달되는 바이트 수: 7바이트 1번째 바이트 = 0x70 ('p') 2번째 바이트 = 0x72 ('r') 3번째 바이트 = 0x69 ('i') 4번째 바이트 = 0x6e ('n') 5번째 바이트 = 0x74 ('t') 6번째 바이트 = 0x0d (CR) 7번째 바이트 = 0x0a (LF) 6
7 hello, world 출력 소켓 프로그램 확장 / 클라이언트 ④ ④ 서비스 요청 및 처리 ① 소켓을 생성 28 if(connect(c_socket, (struct sockaddr *) &c_addr, sizeof(c_addr)) == -1) { 29 printf("Can not connect\n"); 30 close(c_socket); 31 return -1; 32 } 33 34 scanf("%s", buffer); 35 buffer[strlen(buffer)] = '\0'; 36 write(c_socket, buffer, strlen(buffer)+1); 37 38 if((n = read(c_socket, rcvBuffer, sizeof(rcvBuffer))) < 0) { 39 return (-1); 40 } 41 42 rcvBuffer[n] = '\0'; 43 printf("received Data : %s\n", rcvBuffer); 44 45 close(c_socket); 46 } ④ ① 소켓을 생성 ④ 서비스 요청 및 처리 ② 연결할 서버의 주소와 포트를 결정 ⑤ 소켓 연결을 종료 ③ 소켓을 서버에 연결 ④ 커널(kernel)에 개통 요청 7
8 ☎ ☎ 연결요청 “print” ‘p’ ‘r’ ‘i’ ‘n’ ‘t’ \0 “print” internet Hello,world 출력 확장 서버 “print” Hello, world 출력 확장 클라이언트 소켓 2354 IP 주소 IP 주소 9000 소켓 internet ☎ ☎ “hello, world” “hello, world” ‘h’ ‘e’ ‘l’ ‘l’ ‘o’ ‘,’ ‘w’ ‘o’ ‘r’ ‘l’ ‘d’ 실행 실행 터미널-1 / 서버측 실행 $ hello_ext_server ■ 실행 터미널-2 / 클라이언트측 실행 $ gcc -o hello_ext_client hello_ext_client.c $ hello_client print received Data : hello, world test received Data : $ 8
9 ① 연결요청 : 서버 프로그램에 연결 요청 (클라이언트 -> 서버) ① 연결요청 : 서버 프로그램에 연결 요청 (클라이언트 -> 서버) ② ls 요청 : 문자열 ‘ls’ 전송 (클라이언트 -> 서버) ③ 문자열 전송 : 파일 목록 문자열 전송 (서버 -> 클라이언트) ④ 화면 출력 : 파일 목록 문자열 화면 출력 9
10 list.c 실행 실행 터미널-1 / 서버측 실행 $ gcc -o list list.c $ ls 1 #include <dirent.h> 2 #include <stdio.h> 3 4 main( ) 5 { 6 DIR *dp; 7 struct dirent *dir; 8 9 if((dp = opendir(".")) == NULL) { 10 fprintf(stderr, "directory open error\n"); 11 exit(-1); 12 } 13 14 while((dir = readdir(dp)) != NULL) { 15 if(dir->d_ino == 0) continue; 16 17 printf("%s\n", dir->d_name); 18 } 19 20 closedir(dp); 21 } 실행 실행 터미널-1 / 서버측 실행 $ gcc -o list list.c $ ls a.out cli hello_client.c hello_server.c list list.c ser $ list . ser hello_client.c hello_server.c .. a.out list list.c cli $ 10
11 구조체 struct dirent { long d_ino; // I-노드 번호 off_t d_off; // offset unsigned short d_reclen; // 파일 이름 길이 char d_name[NAME_MAX+1]; // 파일 이름 } 함수 함수 디렉토리 스트림 포인터를 반환 파일 정보가 담긴 dirent 구조채 #include <dirent.h> DIR *opendir(const char *dirname); #include <dirent.h> struct dirent *readdir(DIR *dirp); 함수 디렉토리를 닫는다. #include <dirent.h> int *closedir(DIR* dp); 11
12 파일 목록 출력 소켓 프로그램 / 서버 40 while(1) { 41 len = sizeof(c_addr); 42 c_socket = accept(s_socket, (struct sockaddr *) &c_addr, &len); 43 44 length = 0; 45 temp = rBuffer; 46 while((n = read(c_socket, temp, 1)) > 0) { 47 if(*temp == '\r') continue; 48 if(*temp == '\n') break; 49 if(*temp == '\0') break; 50 51 if(length == BUFSIZ) break; 52 temp++; length++; 53 } 54 55 rBuffer[length] = '\0'; 56 57 if(!strcmp(rBuffer, "ls") ) { 58 59 if((dp = opendir(".")) == NULL) { 60 write(c_socket, err_1, strlen(err_1)); 61 } else { 62 while((dir = readdir(dp)) != NULL) { 63 if(dir->d_ino == 0) continue; 64 65 write(c_socket, dir->d_name, strlen(dir->d_name)); 66 write(c_socket, " ", 1); 67 } 68 closedir(dp); 69 } 70 } 71 close(c_socket); 72 } 12
13 ☎ ☎ ☎ ☎ 연결요청 “ls” ‘l’ ‘s’ \r \n internet “a.c b.c c.c” ‘a’ ‘.’ ‘c’ shell ls 서버 $ telnet 192.1.2.3 9000 ls[enter] 소켓 2156 IP 주소 IP 주소 9000 소켓 ☎ internet ☎ “a.c b.c c.c” ‘a’ ‘.’ ‘c’ ‘ ’ ‘b’ ‘.’ ‘c’ ‘ ’ ‘c’ ‘.’ ‘c’ EOF 연결요청 “ls” ‘l’ ‘s’ \0 ls 서버 print ls 클라이언트 소켓 2354 IP 주소 IP 주소 9000 소켓 ☎ internet ☎ “a.c b.c c.c” ‘a’ ‘.’ ‘c’ ‘ ’ ‘b’ ‘.’ ‘c’ ‘ ’ ‘c’ ‘.’ ‘c’ EOF 13
14 실행 실행 터미널-1 / 서버측 실행 $ ls a.out list ls_client ls_server list.c ls_client.c ls_server.c $ ls_server ■ 실행 터미널-2 / 클라이언트측 실행 $ telnet 127.0.0.1 9000 Trying 127.0.0.1... Connected to it (127.0.0.1). Escape character is '^]'. ls . ls_server.c .. a.out ls_client list ls_client.c list.c ls_server Connection closed by foreign host. $ 14
15 파일 목록 출력 소켓 프로그램 / 클라이언트 ☎ ☎ 연결요청 “ls” ‘l’ ‘s’ \0 print internet 2354 9000 소켓 ☎ IP 주소 IP 주소 internet ☎ “a.c b.c c.c” ‘a’ ‘.’ ‘c’ ‘ ’ ‘b’ ‘.’ ‘c’ ‘ ’ ‘c’ ‘.’ ‘c’ EOF 32 if(connect(c_socket, (struct sockaddr *) &c_addr, sizeof(c_addr)) == -1) { 33 printf("Can not connect\n"); 34 close(c_socket); 35 return -1; 36 } 37 38 scanf("%s", buffer); 39 buffer[strlen(buffer)] = '\0'; 40 if((n = write(c_socket, buffer, strlen(buffer)+1)) < 0) { 41 printf("write error\n"); 42 exit(-1); 43 } 44 45 temp = rcvBuffer; 46 while((n = read(c_socket, temp, 1)) > 0) { 47 if(length == BUFSIZ) break; 48 temp++; length++; 49 } 50 51 rcvBuffer[length] = '\0'; 52 53 printf("received Data : %s\n", rcvBuffer); 54 55 close(c_socket); 56 } 15
close(c_socket); ☎ EOF ☎ n = read(c_socket, temp, 1); 16
17 ☎ ☎ 연결요청 “ls” ‘l’ ‘s’ \0 print internet “a.c b.c c.c” ‘a’ ‘.’ ‘c’ 소켓 2354 9000 소켓 ls 서버 ☎ IP 주소 IP 주소 internet ☎ “a.c b.c c.c” ‘a’ ‘.’ ‘c’ ‘ ’ ‘b’ ‘.’ ‘c’ ‘ ’ ‘c’ ‘.’ ‘c’ EOF 실행 실행 터미널-1 / 서버측 실행 $ ls_server ■ 실행 터미널-2 / 클라이언트측 실행 $ ls_cli ls received Data : . ls_server.c .. a.out ls_client list ls_client.c list.c ls_server $ 17
18 네트워크 연결상태는 ping 명령으로 가능 $ ping IP_주소 참고 네트워크 연결상태는 ping 명령으로 가능 $ ping IP_주소 ping 명령이 정상이면 두 컴퓨터 간에 자료의 교환이 가능한 상태 이므로 서버의 보안 설정을 확인하는 것이 좋다. 18