popen()

- 명령어를 shell을 기동 시켜서 열고 pipe로 연결한다.

- 이를 위해서 내부적으로 fork(), pipe()를 사용한다.

- 실행 쉘인 /bin/sh에 -c 옵션을 사용하여 전달

 

pclose()

- popen으로 열린 파이프 핸들 사용을 종료한다.

 

 

 

#include 
#include 
#include 
#include 

int main()
{
    FILE *fp = NULL;
    char cmd[1024] = {0,};
    char buffer[1024];
    pid_t   ppid;
    pid_t   *pid;

    snprintf(cmd, sizeof(cmd), "pidof -x /usr/sbin/sshd");

    fp = popen(cmd, "r");
    if( fp==NULL) {
        return -1;
    }

    fgets(buffer, sizeof(buffer), fp) ;
    printf("%s\n", buffer);
    pclose(fp);
    return 0;
}
실행결과 화면
$ ./a.out 
5967

 

 

 

 

 

 

 

 

 

=============================================

 

그냥 pidof 명령을 실행해준다. 내부의 ssh데몬의 pid를 가져다가

뿌려주는 역할을 한다.

반응형

'Language > C' 카테고리의 다른 글

C FAQ (포인터 선언 에러)  (6) 2012.07.12
mkfifo 함수 예제  (10) 2012.07.06
pipe 함수 예제  (14) 2012.07.06
다차원 배열을 1차원 배열로 변경하고자 할 때  (6) 2011.08.11
C언어 - 스트림(Stream)이란?  (6) 2011.08.11

pipe()

- 하나의 파이프 및 파이프에 대한 두 개의 파일 디스크립터가 생성

- 하나의 파이프를 프로세스들이 공유

#include "sys/types.h"
#include 
#include 
#include 
#include 

#define MAXLINE 4096 /* max line length */ 

/* err_sys("") --> return(1) */

int main(void)
{
    int n, fd[2];
    pid_t pid;
    char line[MAXLINE];

    if (pipe(fd) < 0) {
        printf("pipe error \n");
        return(-1);
        /* err_sys("pipe error"); */
    }

    if ( (pid = fork()) < 0) {
        printf("fork error \n");
        return(-2);
        /* err_sys("fork error"); */

    } else if (pid > 0) { /* parent */

        close(fd[0]);
        write(fd[1], "Hello world\n", 12);

    } else { /* child */
        close(fd[1]);
        n = read(fd[0], line, MAXLINE);
        write(STDOUT_FILENO, line, n);
    }

    return(0);
}
/* The end of function */

=============================================================

파이브열고

포크로 자식 프로세스 만들어다가

read시키는데

이떄, 부모프로세스는 write으로 파이프의 내용을 읽어온다.

결국 위의 코드의 결과는

printf("%s\n", "Hello world");

와 동일하게 나옴. write함수에서 fd들어갈곳에 STDOUT_FILENO플래그를

넣었으니깐.

=============================================================

pipe() 함수는 파일 디스크립터 쌍을 생성하네, 2개 생성하는데.

filedes[2] => filedes[0] Read, filedes[1] Write. 용도로 만든다.

사용법
#include <unistd.h>

int pipe(int filedes[2]);

=============================================================

fork()함수는 Child process 생성하는 기본적인 멀티 프로세싱 함수

사용법
#include <unistd.h>

pid_t fork(void);

=============================================================

close()함수는 pipe로 열린 descriptor 닫아버리는 함수

SYNOPSIS
#include <unistd.h>

int close(int fd);

=============================================================


출처

1. advanced programming in the unix environment

 2. http://gatolu.tistory.com/entry/%ED%8C%8C%EC%9D%B4%ED%94%84-%ED%95%A8%EC%88%98 

반응형

2006.12.31 13:01:27 (*.138.143.127)

14819

54 / 0

이번 시간에는 시리얼 통신에서 자료를 수신하는 부분을 구현하려 합니다. 그러나 송신 보다 수신하는 부분은 생각할 점이 있습니다. 전송이야 이쪽에서 필요할 보내기만 하면 되기 때문에 "언제라는" 시간적인 문제가 없습니다. 그러나 수신은 자료가 언제 올지를 모르죠. 기다려야 한다는 인데, 자료가 때까지 마냥 시리얼 포트만 쳐다 보고 있을 없습니다. 다른 일도 처리 해야죠. 해야할 일이 산더미처럼 쌓였는데, 마냥 포트만 쳐다 없습니다

   

이럴 쉽게 생각할 있는 것이 일을 처리하는 중에 잠시잠시 포트를 확인하는 방법입니다. 가령 예를 들어서 아래와 같이 하는 것이죠.

while( 1)

{

  // 다른 업무를 실행

  if 0 < read( fd, buf, BUF_MAX_SIZE)

  {

    // 수신 자료를 처리

  }

}

물론 이와 같은 방법도 좋습니다만 ?자료 수신 이외의 이벤트 처리, 예로 통신에 에러가 발생하지 않았는지 등을 확인을 위해서는 다른 확인 루틴을 작성하고 if 절을 추가해야 합니다. 그러나 무엇보다도 read()함수가 block 버리면 루틴 자체가 block되어 버리는 매우 문제를 가지고 있습니다.

   

이럴 사용하는 것이 POLL입니다.

   

poll()

POLL 확인하고 싶은 여러 가지 사건( 이하 event) 미리 등록해 놓고 사건들이 발생했는지 확인할 있는 편리한 방법을 제공해 줍니다. POLL 이용한 작업 진행 과정을 정리해 보면,

  1. 체크하고 싶은 여러 event 등록
  2. poll() 함수를 호출하면
  3. event 발생하면 poll() 함수 호출 후에 바로 복귀하지만,
  4. 발생된 event 없으면 하나 이상이 발생할 까지 time-out 시간 만큼 대기하게 됩니다.
  5. event 발생면 해당 event 배열 아이템의 값이 변동이 되는데,
    변동을 확인하여 어떤 event 발생했는지를 있습니다.

장황한 설명 보다는 먼저 간단한 예를 보여 드리고 후에 자세한 설명을 드리도록 하겠습니다. 예제는 이해를 돕기 위해 상수를 사용하지 않았고, 함수로 분리하지 않았습니다.

예제

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <termios.h> // B115200, CS8 등 상수 정의
#include <fcntl.h> // O_RDWR , O_NOCTTY 등의 상수 정의

int main( void)
{
int fd;
int ndx;
int cnt;
char buf[1024];
struct termios newtio;
struct pollfd poll_events; // 체크할 event 정보를 갖는 struct
int poll_state;

// 시리얼 포트를 open

fd = open( "/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK ); // 디바이스를 open 한다.
if ( 0 > fd)
{
printf("open error\n");
return -1;
}

// 시리얼 포트 통신 환경 설정

memset( &newtio, 0, sizeof(newtio) );
newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;

tcflush (fd, TCIFLUSH );
tcsetattr(fd, TCSANOW, &newtio );
fcntl(fd, F_SETFL, FNDELAY);

// poll 사용을 위한 준비

poll_events.fd = fd;
poll_events.events = POLLIN | POLLERR; // 수신된 자료가 있는지, 에러가 있는지
poll_events.revents = 0;

// 자료 송수신

while ( 1)
{
poll_state = poll( // poll()을 호출하여 event 발생 여부 확인
(struct pollfd*)&poll_events, // event 등록 변수
1, // 체크할 pollfd 개수
1000 // time out 시간
);

if ( 0 < poll_state) // 발생한 event 가 있음
{
if ( poll_events.revents & POLLIN) // event 가 자료 수신?
{
cnt = read( fd, buf, 1024);
write( fd, buf, cnt);
printf( "data received - %d %s\n", cnt, buf);
}
if ( poll_events.revents & POLLERR) // event 가 에러?
{
printf( "통신 라인에 에러가 발생, 프로그램 종료");
break;
}
}
}
close( fd);
return 0;
}

  예제를 보시면 struct pollfd 사용했습니다. struct pollfd 내용을 보면 아래와 같습니다.

struct pollfd

{

  int fd;             // 대상 파일 디스크립터

  short events;   // 발생된 이벤트

  short revents;   // 돌려받은 이벤트

};

  1. fd 감시 대상인 디스크립터, 핸들이 되겠습니다.
  2. events 체크하고 싶은 event 모음입니다. 여기서 체크가 가능한 것은 아래와 같습니다.
  • #define POLLIN 0x0001 // 읽을 데이터가 있다.
  • #define POLLPRI 0x0002 // 긴급한 읽을 데이타가 있다.
  • #define POLLOUT 0x0004 // 쓰기가 봉쇄(block) 아니다.
  • #define POLLERR 0x0008 // 에러발생
  • #define POLLHUP 0x0010 // 연결이 끊겼음
  • #define POLLNVAL 0x0020 // 파일지시자가 열리지 않은 같은, Invalid request (잘못된 요청)
  1. revents event 발생 여부를 bit 별로 갖는 값입니다.

   

  , 이제 예제를 보겠습니다.

struct pollfd poll_events; // 체크할 event 정보를 갖는 struct

poll() 사용하기 위한 변수를 선언했습니다. poll_events 에는 감시 대상인 디스크립터와 어떤 event 감시할지 결정해서 bit 값으로 지정해 것입니다.

int poll_state;

poll() 수행한 결과값을 갖습니다. 값은 반드시 체크해야 하는데, 아래와 같은 반환값을 갖습니다.

   

poll() 수행 반환

  

반환

설명

음수

반환 값이 음수라면 치명적인 에러가 발생한 것입니다. 한번 이렇게 음수로 에러가 발생하면 이후 계속 음수값이 날라 옵니다. 거의 대부분 프로그램을 다시 실행해야 됩니다. 반드시 체크해야 겠지요.

0

지정한 대기시간, time-out 지나도록 발생한 event 없습니다.

양수

event 발생했습니다.

poll_events.fd = fd;

감시 대상인 디스크립터를 지정합니다.

poll_events.events = POLLIN | POLLERR; // 수신된 자료가 있는지, 에러가 있는지

체크하고 싶은 event 대해 비트값으로 설정하여 지정해 줍니다.

poll_events.revents = 0;

revents 0 으로 청소해 주고요.

poll_state = poll( // poll() 호출하여 event 발생 여부 확인
(struct pollfd*)&poll_events, // event
등록 변수
1, //
체크할 pollfd 개수
1000 // time out
시간
);

체크할 event 정보를 넘겨 줍니다. 1 체크할 pollfd 개수입니다. 예제를 가지고는 pollfd 개수가 필요한지 이해가 안되시죠. 예제에는 감시하는 디스크립터가 개이지만 프로그램에 따라서는 한번에 여러 개의 디스크립터를 관리할 경우가 많습니다.

   

관리할 디스크립터가 많을 , 각각을 변수로 처리하는 보다 배열로 처리하는 것이 편하겠죠. 이래서 poll() 편리합니다. poll() 변수 하나 외에도 배열을 받을 있으며, 한번의 호출로 모든 event 발생 여부를 확인할 있어 매우 편리합니다.

   

참고

앞으로 강좌를 진행하면서 말씀 드리겠습니다만 poll() 사용하는 다른 장점은 서로 다른 특징의 디스크립터를 사용한다 해도 프로그램 코드를 통일할 있습니다.

예로 rs232c 포트 10개와 tcp/ip 소켓 10개를 한번에 제어하는 프로그램을 작성했을 경우 역시 하나의 배열로 구성해서 poll() 사용할 있기 때문에 rs232c 처리와 tcp/ip 처리하는 프로그램 코드를 통일할 있습니다.

   

1000 time-out 시간으로 발생한 event 없을 경우 poll() event 발생할 까지 time-out 시간 동안 대기하게 됩니다.

시간 값은 msec 1000 1초를 의미합니다. 0 이면? 바로 복귀합니다. -1 이면? evevnt 발생할 까지 기다리게 됩니다. , block 버리죠.

if ( 0 < poll_state)

poll() 함수 결과가 양수라면 event 발생한 것입니다.

if ( poll_events.revents & POLLIN)

발생한 event 중에 POLLIN 있는 지를 확인합니다. POLLIN 해당되는 bit 1 세트되어 있다면 POLLIN으로 AND 값은 0 아닐 것입니다. 이렇게 비트값을 확인하여 event 발생 여부를 확인할 있습니다.

cnt = read( fd, buf, 1024);

write( fd, buf, cnt);

printf( "data received - %d %s\n", cnt, buf);

자료 수신 event 발생했으므로 fd로부터 자료 값을 읽어 들이고, 예제 테스트를 위해 다시 자료를 전송합니다. 또한 화면에도 수신한 자료를 뿌리고 있죠.

예제에 대한 설명은 여기 까지 드리겠습니다. 어떻게 자료 송신부터 수신까지 이해가 되시나요? 다음 시간에는 지금까지의 예제를 좀더 발전시켜서 한번에 여러 포트와 통신하는 방법을 말씀드리겠습니다. 조금씩 조금씩 발전 시켜 나가는 거죠.....^^

   

글을 읽어 주셔서 감사합니다.

게시물을...

목록 수정 삭제

엮인글 주소 : http://forum.falinux.com/zbxe/?document_srl=405838&act=trackback&key=2fe

   

   

2007.11.07 15:35:11 (*.126.183.43)

최강산

좋은공부되었습니다

요즘 통신관련 프로그램을 짜고 있는데 도움이 많이 되네요^^

2008.04.10 17:20:30 (*.94.41.89)

xerxer

감사합니다. 대략 감을 잡는데 도움이 되네요.

번호

제목

글쓴이

날짜

조회

19

TCP/IP 프로그래밍 방법

3

   

장길석

2007-03-19

21449

18

TCP/IP, UDP/IP 2

장길석

2007-03-14

12124

17

TCP/IP, UDP/IP 1

1

장길석

2007-03-14

17479

16

시리얼 통신에서 전송 속도 계산

장길석

2007-03-11

14785

15

CRC 위치는 어디가 좋을까?

장길석

2007-03-11

11932

14

CRC 계산

2

장길석

2007-03-10

19695

13

DLE 프로토콜 소개

5

   

장길석

2007-03-10

15188

12

프로토콜에 대해서

   

장길석

2007-03-10

20903

11

poll 이야기 1

장길석

2007-02-28

12714

10

rs232c 라이브러리 상세 분석

   

장길석

2007-02-23

16492

9

rs232c 통신 라이브러리

6

   

장길석

2007-02-23

16850

  

시리얼 통신 - 자료 수신을 위한 poll

2

장길석

2006-12-31

14819

7

시리얼 통신 예제 전체 설명

장길석

2006-12-29

14978

6

시리얼 통신 - data bit size parity

장길석

2006-12-29

10968

5

시리얼 통신 - start bit stop bit

1

장길석

2006-12-29

11594

4

시리얼 통신 - 통신 속도 결정

장길석

2006-12-29

11466

3

시리얼 통신 - 통신포트 열기

2

장길석

2006-12-29

23781

2

시리얼 통신 - 프로그램 분해 설명 시작!!

장길석

2006-12-29

15260

1

시리얼 통신 첫회

   

장길석

2006-12-24

20326

 

반응형

'Linux' 카테고리의 다른 글

LINUX 디스크, CPU 정보 확인 명령  (14) 2012.07.11
VI 에디터 사용팁  (8) 2012.07.09
NMS의 기본 개념 - 장애관리  (4) 2011.08.23
Unix Domain Socket UDP  (4) 2011.08.19
[명령어]Message Queue 설정 및 확인  (8) 2011.08.11

http://blog.daum.net/pinkky/6818685 (원본)

NMS는 Network Management System의 약자로, 네트워크 관리 시스템 또는 망 관리 시스템이다.

이 말의 의미는 NMS는 네트워크를 관리하는 시스템이며

그 관리 대상이 네트워크 또는 망이라는 의미이다.

즉, 관리 대상이 네트워크 또는 망이라는 사실을 알 수 있다.

말장난 같다는 생각이 들지는 모르겠지만 NMS에서 관리대상의 정의란 매우 중요하다.

 

그렇다면 네트워크란 무엇인가?

네트워크라는 것은 전산 자원간의 연결 전산자원까지 포함해서 - 이다.

"내 PC랑 네 PC랑 연결해서 잘 사용하고 싶어"라는 개념에서

네트워크의 개념이 출발한다고 보면 되겠다.

   

그렇다면 여기서 네트워크 관리자의 임무는 무엇일까?

네트워크 관리자는 이 네트워크가 잘 운영되도록 필요한 모든 조치를 취하는 사람이다.

그렇다면 네트워크 관리 시스템은 네트워크 관리자가 하는 일을 모두 가져갈 수 있는가?

답은 누구나 예상하겠지만 "NO. 아니오!" 이다.

NMS는 네트워크 관리자가 하는 일을 대체하기 시스템이라기 보다는

네트워크 관리자가 네트워크를 잘 관리할 수 있도록 보조하는 역할이라고 생각하는 편이 더 정확하다.

A와 B 두 전산자원을 잘 연결하여 쓰고 있던 어느 날

갑자기 두 전산자원 사이에 연결이 끊어지는 일이 발생하였다.

이러한 경우가 네트워크에서 장애가 발생하였다라고 보는 상황이다.

 

여기서 장애 발생 상황을 인지할 수 있는 경우의 수를 생각해 보도록 하자.

첫 번째 전산자원 A를 사용하고 있던 운영자가 전산자원 B에 대한 연결하여 사용하는 프로그램을 사용하다가 연결이 끊어졌다는 것을 발견할 수 있다.

두 번째 전산자원 A를 사용하고 있던 운영자가 다른 업무 도중 우연히 연결이 끊어진 것을 발견할 수 있다.

세 번째 전산자원 A 주변을 지나가던 누군가(운영자일 수도 있다)가 우연히 전산자원 A 또는 B에 꽂혀 있던 케이블이 빠진 것을 발견할 수도 있다.

네 번째 네트워크 관리자가 아주 부지런한 사람이거나 아니면 할 일이 없어서 네트워크 상태를 수시로 확인하다가 연결이 끊어진 것을 발견하는 경우도 있겠다.

   

그럼 이제 네트워크 관리자가 이 상황을 인지하기까지 걸리는 시간을 생각해 보자.

첫 번째 상황의 경우 사용자가 프로그램을 사용하기 시작하는 시간까지 연결이 끊어진 것을 발견하여 네트워크 관리자에게 통보할 때까지 걸리는 시간이다. 이 시간은 수 초에서 수 시간 또는 수 일이 걸릴 수도 있다. 게다가 이 사용자가 네트워크 관리 업무와 전혀 상관이 없는 사람인 경우 네트워크 관리자에게 말을 안하고 있는 경우도 많이 있다. 

 

두 번째 상황의 경우도 마찬가지이다. 운영자가 네트워크와 상관없는 업무를 하다가 장애를 인지하는 것을 그리 쉬운 일이 아니다. 마찬가지로 알고도 네트워크 관리자에게 전달 않거나 늦게 전달하는 경우가 빈번하다.

 

세 번째 상황의 경우는 그리 기대하지 않는 것이 좋겠다.

오히려 지나가다가 케이블을 건드려 빠지게나 하지 않으면 다행이다.

 

네 번째 네트워크 관리자가 수시로 확인하던 도중 발견하면 아주 다행스러운 경우에 해당된다.

네트워크 관리자가 바로 장애에 대한 조치를 취할 수 있기 때문이다.

   

네트워크는 연결되어 있는 상태에서 의미가 있기 때문에 정상적인 네트워크 구조에서는 연결이 안되는 상태가 있어서는 안된다. 일단 연결된 망에서 필요로 하는 주된 기능이 이 네트워크가 정상적으로 운영되고 있는지 상태를 알고 싶다라는 라는 필요이므로 NMS의 주 기능은 이 장애 관리로부터 시작하게 된다.

 

----------------------------------------------

NMS의 주된 역할이 장애를 인지하는 것이라고 알게 되었다.

   

그럼 이제 장애를 어떻게 인지할 것인가를 생각해 보자.

   

먼저 가장 쉬운 것은 모두가 아는 것처럼 대상 장비 또는 시스템에 ping을 때려 보는 것이다.

조금 더 잘 아는 사람은 SNMP Polling을 한다고 말할 것이다.

   

먼저 이 ping이라는 것에 대해 알아보도록 하겠다.

네트워크 분야에 종사하는 사람이라면 이 ping이라는 것이 뭐하는 것인지는 다들 잘 알고 있을 것이므로 이 ping으로 네트워크 관리를 어떻게 하면 되며, 문제점이 무엇인가만 살펴보도록 하자.

   

ping으로 네트워크를 관리하는 방식은 매우 간단하다.

관리 시스템으로부터 ping request에 대한 response가 없으면 장애로 보는 것이다.

그럼 네트워크 관리자가 모든 전산자원의 IP에 모두 ping을 때리고 있으면 어떨까?

그리고 ping이 안되는 장비가 있으면 조치를 하는 것이다.

일견 아주 단순하고 아무 문제도 없어 보인다.

   

그러나, 그렇게 단순한 문제만은 아니다.

여러분이 command(cmd) 창을 열고 자기 ip로 ping을 때려 보자.

========================================================================

C:\Documents and Settings\R51>ping 147.6.97.1

Pinging 147.6.97.1 with 32 bytes of data:

Reply from 147.6.97.1: bytes=32 time<1ms TTL=255

Reply from 147.6.97.1: bytes=32 time<1ms TTL=255

Reply from 147.6.97.1: bytes=32 time<1ms TTL=255

Reply from 147.6.97.1: bytes=32 time<1ms TTL=255

Ping statistics for 147.6.97.1:

    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),

Approximate round trip times in milli-seconds:

    Minimum = 0ms, Maximum = 0ms, Average = 0ms

C:\Documents and Settings\R51>

=========================================================================

   

그럼 Reply from 어쩌고 하면서 응답이 3~4번 떨어질 것이다. ttl=xx ms 하는 구문과 함께 말이다.

그럼 이 ping에 대한 응답이 네 번 중 한 번 없다고 장애일까?

아님 두 번? 아님 세 번 모두를 장애로 볼까?

장비가 다른 트래픽을 처리하느라 바쁘다면 ping 응답이 안 올 수 있다.

(ping은 우선 순위가 밀리기 대문이다.)

또는 네트워크 대역이 그리 좋지 못해서 timeout (보통 0.8ms) 이 나는 경우도 있다.

그럼 그런 것을 고려해서 0.8을 1.2나 2.0 정도로 늘려 줄 수도 있다.

도스에서 win98에서 xp에서 그리고  리눅스나 sun, hp 등 unix 시스템에서 이 ping utility의 사용법은 조금씩 다르며, 네트워크 관리자라면 ping의 옵션 정도는 알고 있어야 한다.

   

지금 여러분은 네트워크 관리자의 관리 정책이 적용되는 상황을 보고 있다.

장애정의 : 자원의 ip에 ping을 실행하여 응답이 없으면 장애로 인지한다.

기준설정 : 비지니스 rule 적용

         기준 1) 응답 세번에 모두 답이 없는 경우만을 장애로 인지한다. timeout은 1.5ms로 한다.

         기준 2) 응답이 한번이라도 없으면 무조건 장애로 본다. timeout은 0.8로 한다.

         기준 3) 저 위에 있는 것을 장비 또는 ip 별로 다 다르게 주었으면 좋겠다.

                   나중에 바꿀 수도 있으면 더 좋겠다.

         추가 조건 ) ping이 한번 빠지면 노란색, 두번 빠지면 빨간색으로 해주었으면 좋겠다.

                         ip가 없는 interface는 어떻게 하느냐... 등등...

기준 1은 굉장히 Loose하게 적용되는 경우이며, 약간의 지연은 장애로 보지 않겠다는 정책이다.

기준 2는 타이트하며 작은 지연도 허용되지 않는 크리티컬한 네트워크 운영 정책이다.

기준 3은 대부분의 사이트에서 원하는 방식이며, 추가조건도 꼭 따라 붙는다.

   

(이런 조건을 충족하는 NMS가 잘 아는 whatsup gold 나 openview nnm이라는 제품이다.

뭐 아는 사람은 다 알겠지만, 개인적으로 whatsup gold는 ping 장애관리 전문 제품으로 가격대비 성능으로는 최고라고 보고 있다. openview nnm은 비싸고 또 좋은 제품이다. 다만 쓰기가 매우 어렵고(영어) 우리나라 관리자들은 별로 좋아하지 않는다. 여기서 사족을 조금 더 달자면 openview nnm은 정말 괜찮은 제품이다. EMS나 NMS를 만들려고 고민을 해본 사람은 알겠지만, OV에는 이러한 고민에 대한 부분이 거의 다 수용되어 있다. 단지, UI가 너무 Old 하다는 것이 단점. 또 기능이 너무 많다 보니 쓰기가 어려워서 단점. 하지만 거의 다 필요한 기능들이다.) 

   

다시 장애 감지로 돌아오자.

이제 ip가 없는 interface의 경우를 살펴보자.

ip가 없는 interface라... 무엇이 있을까? 요새는 tcp/ip 환경으로 거의 대부분 구성되어 있지만, 아직도 WAN 구간에는 ATM이나 Flame relay 또는 광으로 된 연결 구간들이 있고, 대부분 ip가 없다. 또 장비의 카드 중에 장애가 나면 장비가 제대로 동작할 수 없는 것들도 있다.

이런 경우도 장애로 보아야 하기 때문에 난감한 일이 아닐 수 없다.

   

우리는 이러한 이유들 때문에 SNMP라는 프로토콜을 사용하여 네트워크 관리를 하게 된다.

SNMP를 지원하는 장비라면 MIB II에서 정의한 interface의 상태 ifoperstatus를 보고 장애인지 아닌지를 판별하는 것이다. 여기까지는 좋아보인다. 이론상으로도 그럴듯해 보인다.

   

그러나 네트워크 관리자는 머리가 복잡해 진다.

여기 인터페이스가 수십개 되는 장비가 있는데, 나는 그 중에 두 개의 상태만 알면 된다.

어떻게 해야 할까?

방법 1) 내가 원하는 인터페이스만 관리하도록 등록하고 이것들만 관리한다.

방법 2) 일일히 등록하기 어려우니, ifadminstatus와 ifoperstat가 다른 것만 체크해서 알려준다.

방법 3) 어쨌거나 up 상태였다가 down 상태이면 문제가 생긴 것이니 down이라고 알려주는 놈만 추려서 장애로 알려준다. 물론 내가 원하는 interface의 경우에만. trap을 쓰면 좋겠다.

   

제대로 된 NMS에서는 이런 것들을 관리자의 판단에 따라 설정할 수 있어야 한다.

그럼 설정하는 화면들이 많이 늘어난다. 고로 또 복잡해진다.

   

네트워크 관리자들은 복잡한 기능을 싫어한다.

그래서인지 nms가 인공지능처럼 동작하기를 원하는데...

프로그래은 인공지능이 아니다. 최소한 어떤 것이 중요한 인터페이스인지, 어떤 것을 장애로 볼 것인지는 알려주어야 한다. 아니면 default 값을 쓰게 되는데.. default 값을 쓰면서 nms가 틀렸다고 말해서는 조금 곤란하지 않겠냐는 거다.

   

또 요새 등장한 복병 중 하나가 보안 방화벽이다.

장비에서 snmp를 지원하는 것, snmp를 설정하는 것이 1차이고, 보안 정책도 확인해 보아야 한다.

snmp는 well-known port 이므로 보안 정책 상 허락하지 않는 경우도 있다. port를 바꿀 수도 있지만, manager와 agent가 모두 이 기능을 지원해야 한다. 이놈의 snmp는 simple network management protocol 이라는데 simple이 아니라 너무 어려워 보인다.

   

사실 더 어렵고 복잡한 뭐 CMIP이나 CORBA라는 것들이 존재하는데... 거의 시장에서 사라졌다.

사람들은 더 정확하고 잘정리된 표준 대신 간단한 표준을 선택하였다. 그래서 더 복잡해졌다.

   

어찌되었건 요약하자면 네트워크 관리자는 장애 관리를 하기 위해서 가장 많이 쓰는 icmp ping과 snmp 방식을 가지고 NMS를 구축할 수 있다.

   

이 때 필요한 것은 "좋은 NMS(쉬운것이 항상 좋지만은 않다)"와 "적절한 네트워크 관리 정책"이다.

------------------------------------------

앞에 두 개의 글에서 NMS의 중요한 기능 중에 하나는 장애를 자동으로 인지하고자 하는 것이고,

그러자면 장애를 판단하는 기준(정책)이 매우 중요하다 라는 것을 장황하게 설명해 보았다.

   

그렇다면 장애여부를 판단하는 기준을 어느 정도의 주기로 적용하면 좋을 것인지 살펴보자.

우리가 운영하는 네트워크에서는 icmp ping 또는 snmp polling 시 timeout을 1.0에 retry 3회 시에도 반응이 없으면 장애로 보기로 정책을 세웠다.

   

우리의 네트워크에는 장비가 10개 있다.

그럼 장비에 ping 또는 snmp request를 1분에 한번씩 보내보자.

10개를 죽 돌면서 ping을 해보고 상태를 반영하고 또 1분 후에 같은 일을 반복 수행한다.

별로 문제가 없어 보인다.

   

갑돌이네 네트워크에는 장비가 100개 있다.

역시 장비에 ping 또는 snmp request를 1분에 한번씩 보내보자.

이번에는 100개를 돌면서 같은 일을 한다. 근데 문제가 생겼다.

1분이 지났는데... 아직 100개의 장비 리스트의 끝까지 다 못갔다.

그럼 둘 중에 하나를 선택해야 한다.

1-뒤에 거는 무시한다.

2-걍 뒤에서 계속 진행하고 다 끝난다음 다시 시작하는 걸 생각해 본다.

조금 골치 아파진다.

프로그램을 수정하기는 어려우니 상태 확인 주기를 늘린다.

한 5분쯤으로 해보자. 잘 되는 거 같다.

   

을순이네 네트워크에는 장비가 1000개 있다.

역시 장비에 ping 또는 snmp request를 1분에 한번씩 보내보자.

이번에는 1000개를 돌면서 같은 일을 한다. 역시 같은 문제가 생겼다.

1분이 지났는데... 아직 100개 끝까지 다 못갔다.

그럼 둘 중에 하나를 선택해야 한다.

1-뒤에 거는 무시한다.

2-걍 뒤에서 계속 진행하고 다 끝난 다음 다시 시작하는 걸 생각해 본다.

조금 더 골치 아파진다. 반영주기를 10분으로 늘렸다.

같은 문제가 생긴다. 게다가 장애 반영이 너무 늦어진다.

장애가 나거나 복구된 것을 10분 주기로 알 수 있다.

결국 프로그램은 수정되어야 한다.

한 번에 리스트를 10개로 분할해서 돌린다.

1000개를 100개씩 나누어서 열심히 상태를 체크한다. 3분이면 된다. 다행이다.

   

병철이네 네트워크에는 장비가 10000개 있다.

위에서 문제를 해결한 프로그램이 있으니 10개로 나누어서 돌린다.

한번에 1000개씩 리스트를 나누어서 체크한다.

저런.. 잘 안된다. 반영주기를 10분으로 늘렸다.

같은 문제가 생긴다. 게다가 장애 반영이 너무 늦어진다.

프로그램은 또 수정되어야 한다.

한 번에 리스트를 100개로 분할해서 돌린다.

10000개를 100개씩 나누어서 열심히 상태를 체크한다. 3분이면 된다.

근데 프로세스가 한꺼번에 100개가 뜨고 시스템에 부하가 걸린다.

   

근데 10000대의 장비가 다 중요하지 않댄다.

그럼 중요한 거 100개는 1분으로 하고, 나머지는 걍 10분으로 했으면 좋겠다.

근데.. 아주 아주 중요한 장비 5개를 특별히 10초 정도로 관리 했으면 좋겠다.

물론 실시간이면 제일 좋겠지만 특별히 10초 정도도 괜찮겠다.

   

저런... 프로그램이 대폭 수정되어야 한다.

우리의 NMS는 특정 장비 또는 그룹 별로 상태 확인 주기를 다르게 줄 수 있어야 하고,

상태 확인 프로그램은 이 설정내용에 딸 가변적으로 동작해야 하며,

장비 갯수를 알아서 판단해서 10개로 쪼갤 것인지 1000개로 쪼갤 것인지를 결정해야 한다.

   

얼핏 보면 인공지능 프로그램 같다.

그러나 여기서도 반드시 인풋이 있다.

1. 내가 관리해야 하는 대상과 갯수가 정해져 있다.

2. 상태반영 주기를 정의해야 한다.

   

따라서 관리자는 이러한 정책을 정하고 NMS에 반영할 수 있어야 한다.

이러한 정책들을 입력하고 설정하는 화면이 프로그램에 추가된다.

   

네트워크가 커질수록 관리대상의 종류와 중요도가 달라질 수록 이러한 설정 메뉴들은 점점 추가되며,

프로그램은 점점 복잡해 질 것이다.

   

   

----------------------------------

네트워크 장애관리에서 가장 중요한 것은 관리정책과 좋은 NMS이다.

   

세번째 얘기에서는 ping response check와 snmp polling을 통한 장애 인지에 대해서 생각해 보았다. 전체 네트워크 장비에 대해 이렇게 일일히 체크를 한다는 것은 사실상 실시간 체크가 어렵다.  그렇다면 실시간으로 상태를 반영할 수 있는 방법이 무엇인가?

   

바로 SNMP Agent가 올려주는 상태에 대한 정보를 직접 받는 것이다.

이것이 잘 알려져 있는 SNMP Trap이라는 것이다. SNMP Trap은 장비가 중요한 장비 자체의 상태 변화를 SNMP Manager에게 알려주는 것인데, 그럼 어떤 경우에 상태를 알려줄 것인가?

   

표준에 의하면 여섯가지의 경우에 Trap을 발생시킨다.

SNMP Cold Start / SNMP Warm Start / SNMP Link Down / SNMP Link Up / SNMP Authentification Failure / SNMP EGP Down 이다.

   

문제는 이 여섯 가지의 경우를 통해서는 장비 CPU가 높아져서 죽기 직전인지, 장비 자체가 죽어버렸는지 등등 알 수 없는 것이 너무나 많다는 사실이다.

네트워크 관리자 입장에서는 알고 싶은 정보가 많기 때문에 업체에서는 Private MIB을 통해 추가적인 정보를 제공한다. Private MIB은 벤더별로 다르므로 벤더에서 제공한 MIB 파일과 문서들을 참조해야 하며, NMS는 이러한 Private MIB에서 제공하는 SNMP Trap 정보를 해석할 수 있는 능력을 가지고 있어야 한다.

   

모든 장비가 이러한 Private MIB을 충분히 제공할 것으로 기대해서는 안된다.

물론 이러한 MIB을 충분히 제공하는 장비들도 있다.

   

문제는 NMS에서 이러한 Private MIB을 어떻게 처리할 것인지 결정해야 하며,

역시 좋은 NMS는 이러한 기능들을 충실히 제공한다.

약간 좋은 NMS는 이러한 기능을 약간(잘 알려진 장비에 대해서만) 제공한다.

당연히 이러한 기능이 없는 NMS도 많이 있다.

여러 가지 기능을 충분히 지원하는 NMS는 가격이 비싸며, 사용하기 어렵다고 느껴진다.

   

여기에서 추가적으로 알아두면 좋은 것이 syslog이다.

대부분의 장비는 자체적으로 log를 메모리에 남기고 있는데,

대부분의 네트워크 관리자들은 이 log를 참조하여 장비 관리를 하고 있다.

그러나, 이 log들은 장비가 리부팅되면 없어져 버리며,

일일이 장비에 login 하여 확인해 보아야 하는 단점이 있다.

수십대의 라우터에 모두 로그인하여 log를 볼 수는 없기에,

대부분의 라우터, 스위치들은 syslog 프로토콜을 이용하여

이 log들을 syslog 서버로 보내는 기능을 제공한다.

   

syslog는 형식이 단순하게 종류, 시간, 장비명(서버명), 로그로 구성되어 있으므로

관리자가 쉽게 인식이 가능하며, 항상 장비에서 보던 형식이므로 친숙하다.

자연스럽게 네트워크 관리에 많이 이용되고 있다.

   

UNIX 시스템의 경우 syslogd라는 데몬이 기본 프로세스로 제공되므로,

장비들로부터 이 syslog들을 받아 로그들을 저장하며, NT는 기본 기능이 아니라 키위 등 syslog를 받아서 저장해 주는 상용 프로그램을 사용해야 한다.

SUN의 경우 /etc/syslog.conf 파일을 이용하여

받게 될 syslog 종류, 저장될 파일명 등에 대한 환경을 설정할 수 있다.

   

장비의 숫자가 많아지거나, debug 모드 등으로 syslog를 받게 되는 경우,

엄청난 log의 양 때문에 관리하기에 부담스러워 질 수 있으며,

특히 FWSM 같은 장비는 firewall log를 syslog로 발생시켜 주는데...

초당 몇백건의 syslog를 처리할 수 있는 프로그램이 별로 없기 때문에

이런 종류의 방화벽을 도입할 때는 관리 툴에 대해 고민을 해보는 것이 좋겠다.

   

============================================================================

   

약간의 여담을 달자면... 벤더들에 대한 불만이 많다. 

웬만하면 규약을 지켜서 만들고, Pravate 아래 구조를 함부로 바꾸지 말며, 문서를 잘 찾을 수 있도록 해 주었으면 좋겠다. 대체 홈페이지에 가도 어느 구석에 이 mib들이 박혀 있으며 뭐에 쓰는 건지 알 수가 없다. 버전이 올라간다고 공지도 없이 MIB Tree 구조를 바꿔버리는데 대책이 없다. 뭐 그나마 SNMP 라도 지원해 주면 고맙기는 하다.

------------------------------

 

앞서 네트워크에서 장애를 인지하는 방법에 대해 몇 가지 살펴 보았다.

   

1. ping 을 이용한다. => 제일 쉽다. 그러나 정책을 잘 세워야 한다.

   

2. snmp polling 을 이용한다.

 => 다소 쉽다. 표준 MIB이라 불리우는 mib II 정보들을 이용한다.

 => Private mib의 영역으로 가게 되면 난해해진다.

 => 역시 정책이 들어가게 되면 ping의 경우보다 10배는 어려워진다.

   

3. snmp trap을 이용한다.

 => 다소 쉬우나 장애 상황을 분리해 내는 것이 어렵다.

 => 이건 Private mib이 필수 사항이다.

 => 역시 정책도 필수 사항이다.

 => 이 trap은 syslog와는 달리 여러 개의 variable들로 나누어져 올라오므로

     관리자가 받아서 문장으로 만들어 주어야 한다. => 때문에 복잡해질 수 있다.

     이 variable의 갯수나 형식은 정해져 있지 않다.

   

4. syslog를 이용한다.

 => 다소 쉬우나 장애 상황을 분리해 내는 것이 어렵우며, log의 홍수에 빠질 염려가 있다.

 => 장비를 만지는 엔지니어들은 제일 선호하나, 관리자들은 좋아하지 않는다.

 => 그냥 로그다.

   

그러나...

네트워크에서 장애가 발생하는 것을 파악하는 것은 이렇듯 명확하지만은 않다.

최근들어 Application의 비중이 높아지고 장비의 사양이 올라가면서...

장비에 들어가는 OS들도 점점 복잡해졌고 자연히 장비 OS의 버그 때문에 발생하는 장애도 많이

발생하게 되었으니... 이런 것들은 장애라고 인식하기가 그리 쉽지만은 않다.

   

어찌되었건 "빠른 장애인지"라는 요구사항이 어느 정도 총족된다면,

관리자들은 다음 단계를 요구하게 된다.

바로 장애를 예고해 주는 시스템이다.

   

사실... 장애징후를 나타내는 것은 그리 많지 않다.

흔히 볼 수 있는 증상이 장비에서 Major 또는 Alert!이라고 정의되는 Log를 발생시킨다거나

장비 또는 카드, 회선의 불량에 의한 회선 에러(CRC, Collision 등)가 쌓이고 있다거나

장비가 죽기 직전 CPU 사용율이 치솟았다거나, 아니면 측정 성능 지표들이 높아졌다거나

L4나 L7 장비의 경우 Session에 흐르는 데이터가 전혀 없다거나 등등의 현상이 있을 수 있는데,

이러한 것들은 Log 쪽을 제외하고는 성능관리 쪽에 더 가깝다.

   

그러나 장애예보라는 면에서 보자면 장애관리에 포함되기도 하므로,

이것도 보는 시각에 따라 장애관리에 포함시키기도 한다.

   

이렇게 장비 성능이 일정 수치를 벗어나면 장애징후로 보는 방법은 크게 두 가지가 있다.

하나는 NMS에서 주기적으로 장비에서의 주요 성능 지표들을 체크하다가 정해진 값을 벗어나느 경우

경보를 올려주는 방법이고, 또 하나는 장비 자체가 스스로 특정 값 이상인 경우 SNMP Trap이나 syslog로 알려주는 경우이다.

전자는 장비가 해당 성능 지표에 대해 값만 제공해 준다면 NMS의 역량에 달려있지만,

Trap의 경우에는 해당 장비에서 그러한 기능을 제공해 주어야만 가능하다.

   

관리자의 입장에서 볼때는 두 가지 경우 모두 가능했으면 하는 경우가 많으므로,

단 두 가지 방법은 데이터를 얻게되는 경로가 다르기 때문에 

이 두 가지 정보를 하나로 통합해 주는 기능이 NMS에서 제공된다면 더욱 좋을 것이다.

   

추가적으로 네트워크 관리자들은 성능 지표가 임계치를 한번 초과한다고 바로 알려주는 것이 아니라 

최소 2회 이상 초과한 경우였으면 좋겠다. 지표에 따라 초과가 아니라 특정 값 미만인 경우,

혹은 특정값 사이를 벗어난 경우 등등 다양한 옵션을 요구하는 경우가 있다.

그리고 CPU인 경우에는 CPU라는 메세지를, 메모리인 경우에는

메모리라는 별도의 메세지를 요구하는 경우도 있다.

또 임계치 경보를 발생시켰더라도 해당 값 아래로 떨어지면 복구용 메세지를 발생시킨다거나,

아니면 한번만 경보를 발생하는 것이 아니라 특정 지표가 계속 임계치를 벗어나는 경우

재경보를 발생시키는 등의 다양한 기능들을 요구하는 경우도 있다.

   

따라서 장비의 사용 상태를 측정하여 경보로 알려주는 예보 시스템을 제대로 구축하기란

그리 쉬운 일이 아니다. 

 

---------------------------------------

지금까지 네트워크 관리에서 장애 판단 및 예보 기능에 대해 알아보았다.

   

이번에는 이 장애 판단 및 예보에 가장 흔하게 사용되는 LOG에 대해서 알아보기로 하자.

   

대부분의 장비들은 장비 자체에 장비의 운영에 관련된 LOG를 기록한다.

때문에 네트워크 관리자들은 장비에 접속하여 이 LOG들을 분석함으로써 장비의 현재 상태나

과거의 운영 상태들을 관리할 수 있다.

   

그러나 이 LOG들은 휘발성이므로 (장비에는 메모리가 있을 뿐 DISK가 없다.)

장비가 문제가 생겨 부팅하고 나면 모두 사라져 버린다.

   

대부분 장애 발생시에 장비를 껐다 켜는 경우가 많으므로 추후 LOG를 보고자 하면 이미 모두

사라져 버린 후라 장애의 원인을 파악하기란 쉽지가 않다.

   

따라서 대부분의 장비는 SNMP Trap 또는 Syslog의 형태로 LOG를 기록할 수 있는 다른 시스템에

이 LOG를 전송할 수 있는 기능을 제공한다.

   

가장 많이 사용되는 Cisco 등 대부분의 벤더는 SNMP 보다는 syslog 형태로 더욱 장비의 LOG 형식에

가깝게 LOG를 기록할 수 있도록 해 준다.

   

그렇다면 이 LOG들은 어떤 방식으로 남겨지는가?

   

Cisco의 경우 syslog를  Alert!, Critical, Error, Warning, Notification, Information, Debugging Mode 의 7가지 모드로 제공한다. syslog를 debugging mode로 설정하면 어느 정도의 log가 쌓이게 될까?

   

실제... 이 라우터에 이상이 있거나 이상 패킷이 많아 log가 매우 많이 발생하고 장비에 부하가 걸렸던 경우(였던 것으로 추정) debug mode 가 걸려있던 장비가 갑자기 CPU 사용율이 치솟으며 reboot 되는 경우를 본 적이 있었다. 75XX급 이상 대형 장비인 경우 이 debugging mode로 10대 정도만 log를 받아도 하루 100만건이 넘는 log들이 쌓이는 것을 볼 수 있는데 하루 백만건이면 NMS에서 관리하기에도 버거운 양의 데이터이다.

   

어쨌건 이 LOG들을 통합 저장하고 모니터링 할 수 있는 기능도 NMS의 필수 기능이다.

주요 기능은 LOG를 받아서 실시간으로 뿌려줄 수 있을 것.

그리고 모두 저장한 후 검색 조건으로 골라서 볼 수 있을 것.

그리고 가능하다면 통계를 내 줄 것.

   

이 짧은 세 줄에  LOG 관리 시스템의 모든 것이 담겨 있다.

-----------------------------------

 

LOG 관리에 대해 좀 더 자세히 알아보자.

   

사실 LOG 관리라는 것은 앞서 말한 것처럼 아래의 세 가지로 요약된다.

   

실시간 LOG 모니터링 => 문제 LOG 발생 시 경보

모든 필요한 LOG의 저장 => 가능하면 전부 다

저장된 LOG의 검색 => 통계 기능도 있으면 좋음

   

   

장비들의 LOG를 서버로 받기 위해서는 해당 장비들이 syslog 프로토콜을 지원하는지 확인하고

해당 장비의 syslog 기능을 enable 해주면 된다. 그리고 LOG의 등급(종류)을 설정해 준다.

여기서 필요한 것이 "관리 정책"이다.

altert이나 critical 만 설정하면... 실제 해당 네트워크에서는 중요한 LOG를 놓칠 수 있다.

때문에.. 실제 운영자나 엔지니어들은 debug 모드를 선호한다.

그러나 이것은 장비에 부하를 줄 수 있고, debug 모드로 올라오는 LOG들을 모니터링한다는 것은

별로 즐겁지 않은 일이므로, 관리자의 성향과 필요성에 따라 모드를 적절히 설정한다.

   

syslog 서버에서는 unix 시스템인 경우 디폴트로 제공하는 syslogd가 /var/log/아래에 파일로 쌓아준다.

수정하고 싶으면 /etc/syslog.conf 파일을 열어 적절히 수정하면 된다.

   

windows 서버의 경우 syslog가 기본으로 제공되지 않으므로,

syslog 데몬 프로그램을 구해서 설치해야 한다. kiwi 같은 것들이 많이 쓰이며 유료이다.

대부분 외산이며, 국산 프로그램은 단품보다는 로그 분석 솔루션에 가까운 것들이 몇 개 있다.

외산의 경우 기능은 매우 단순하다. syslog를 모아서 보여주고,  파일로 저장해 준다.

   

작은 네트워크에서는 이런 솔루션들이 매우 유용하게 쓰인다.

그러나 대형 네트워크에서는 얘기가 달라진다.

장비에서 올려주는 LOG들이 하루 몇십만건, 몇백만건이 이르게 되면,

이 LOG를 파일로 관리한다는 것이 얼마나 노가다 작업이 되는지 해본 사람은 알 것이다.

몇 기가나 되는 파일 덩어리에서 원하는 LOG들을 찾아내기가 얼마나 어려운가.

때문에 대량의 로그를 관리하기 위한 DB가 등장한다.

여기서 네트워크 관리자는 고민에 빠지게 된다.

DB가 등장하면 이제 이 S/W는 네트워크 관리자의 영역을 벗어나

개발의 범주로 넘어가 버리기 때문이다.

LOG를 저장하기 위한 DB 구축 비용과 이를 제대로 볼 수 있게 하기 위한 개발비는

네트워크 관리자에게 상당한 부담을 안겨 준다.

   

LOG를 관리하는 것이 얼마나 중요한가?

LOG 관리 시스템은 꼭 있어야 하는가??

------------------------------------------

 

LOG 관리 프로그램 사용에서 LOG 관리 시스템 구축으로의 개념 전환이란 그리 쉽지만은 않다. 이 시스템이라는 것은 H/W, S/W, 그리고 개발이 들어가야 하므로 돈이 어마어마하게(!) 들어가기 때문이다.

   

대부분의 경우 LOG 는 대용량 데이터이다.

대용량 데이터의 대한 처리와 투자 비용은 돈과 연관된 곳에서는 그리 크게 여져지지 않는다. 통신사에서의 콜 횟수나 문자에 대한 데이터 들 또는 카드사의 기록들, 그리고 은행 입출금 기록들이 그러하다. 이런 과금, 결제에 관련된 데이터들은 매우 중요하며 하나라도 유실될 경우 기업의 손실 또는 이익과 직결되므로 대용량일지라도 하나도 빠짐없이 매우 소중히 다루어지게 된다.

그리고 그 결과물도 매우 명확하다.

접속 기록 1회 20초 500원. 하나 놓치면 500원 손실.

투자비용 10억이면 100억 이익.

이 얼마나 명확하며 알기 쉬운가.

   

그러나 이 네트워크 관리에서 발생하는 LOG는 그렇지가 않다.

애시당초 snmp나 syslog 라는 프로토콜 자체가 udp라는 손실을 허용하는 것인데다가,

데이터가 유실된다고 해도 당장 눈에 보이는 손실이 발생하는 것이 아니기 때문이다.

게다가 그 결과물도 그리 명확하지 않다.

네트워크에 장애가 나서 원인이 뭐냐고 물으면 걸핏하면 log가 남아있는 게 없어

알 수 없다고 한다. 그래서 그럼 시스템을 구축하라고 하면 그것도 구축하려면 수억이 든단다.

그래서 그럼 근거를 가져와 봐라(ROI 분석) 하면 안 가져 온다.

어쨌건 장애가 하도 발생하니 수억을 들여 구축해 주었더니,

이번에 장애가 발생한 부분은 구축 범위에서 제외된 곳에서 발생한 것이란다.

구축범위 내라서 다행히 로그가 남아 있는 경우도 뭔가 명확한 게 없단다.

그래서 이유를 물었더니 디버깅 모드가 아니라서 자세하지 않단다.

대체 무슨 소린지 알 수가 없다.

 

이런 식이니 경영진이 보기에는 개념 자체도 명확하지 않은 이 LOG 관리 시스템이라는 것이

사기같다는 생각이 들 수 밖에 없다.

특히 구축할 때는 마치 만능이던 것처럼 떠들어대던 업체 말만 듣고 구축 했는데,

막상 구축하고 보니 이래서 안되고 저래서 안되고 한다.

업체가 사기를 쳤거나 네트워크 담당자들이 무능하거나 둘 중에 하나라고 생각할 수 밖에...

그래서 담당 부서에서 뭔가를 구축하려고 한다 해도 투자를 할 수가 없다.

그러니 점점 더 모르겠다.

그래서 뭔가 알 수 없는 문제가 발생하면 항상 네트워크 쪽을 의심할 수 밖에 없다.

---------------------------------

 

 

일반적인 장애 관리에서 사용하는 기법(폴링)는 장애가 난 후 그것을 빨리 알려줄 수는 있지만

장애가 왜 발생했는지는 알기는 어렵기 때문에 사실 네트워크의 장애 발생 시

제일 명확한 원인을 제공해 줄 수 있는 것은 어디엔가 남아 있는 LOG가 맞다.

그러나 LOG 관리 시스템은 구축하기에 비용이 많이 든다는 점과

비용대비 결과물이 그리 만족스럽지 못하다는 것(돈으로 환산되지 않는다는 점...),

그리고 시스템을 구축하고 유지 관리할 만한 전문가가 별로 없다는 것이다.

그렇더라도... 관리를 하지 않을 수는 없으니... 그것도 문제다.

   

어쨌거나.. 비용과 효율성에 대한 것은 일단 제쳐 두고

실제로 LOG 관리 시스템을 구축하는 절차에 대해 생각해 보자.

   

항상 그렇듯이 제일 처음 할 것은 관리 대상과 정책을 정하는 것이다.

   

1) 어떤 장비들의 로그를 관리할 것인가?

2) 장비들의 logging 레벨(혹은 trap level)을 어느 정도로 정할 것인가?

그리고 이 두 가지를 고려해 1일 평균 log 량을 산정한다.

이것은 도입할 시스템과 구비해야 할 DISK의 용량을 정하는데 백데이터가 된다.

   

하지만 이것들 보다 먼저 해야 하는 일이 있다.

그것은 무엇을 보고자 하는지 정하는 것이다.

보고자 하는 LOG가 무엇인지, 어떤 형태로 보기를 원하는지 결정하고 시작해야 한다.

   

이 부분은 아주 중요하지만 간과하고 진행하다가 최종 단계에서야

되니 안되니 하며 개발자와 발주자 사이에 큰 문제로 불거지게 되는 경우가 허다하다.

   

특히 장비가 로그를 어떤 형태로 남기는지 확인하는 것도 중요한 이슈 중에 하나인데

이에 따라 개발방법과 개발해야 하는 범위가 전혀 달라질 수 있기 때문이다.

   

시스템 도입 전에 관리하고자 하는 장비들이 로그를 전송하는 방식을 확인해야 한다.

대부분이 syslog 또는 trap을 지원하지만... 그렇지 않은 장비들도 많이 있기 때문이다.

   

다행히 별도의 포트를 통해 udp 또는 tcp 방식으로 로그를 전송해 준다면,

이를 받아 주는 프로그램을 개발해야 한다.

장비들의 EMS를 통해서 자체 프로토콜로 logging을 하는 장비라면

EMS로 부터 log를 가져오는 방법을 연구해 이를 프로그램 해 주어야 한다.

이런 식으로 각각의 장비 별로 log를 통합할 수 있는 방법을 찾는다.

아예 통합이 불가능한 장비라면, 다음 장비 교체 시기에 이에 대한 업그레이드나

교체도 고려해야 할 것이다.

   

이러한 절차들이 끝나야 어떤 시스템을 도입할 것인지 결정할 수 있게 된다.

   

그럼 log 관리 프로그램을 상용으로 할 것인지, 아니면 개발을 할 것인지 결정해 보자.

   

상용 로그 분석 시스템은 네트워크 관리 용도 보다는 web log 분석이나, 방화벽 로그 분석 등의

용도로 많이 쓰이기 때문에 네트워크 용으로 사용하려고 하다 보면 여러 가지로 수정해야 하는

경우가 많다. 따라서 처음부터 개발을 하는 것이 더 나을 수도 있다.

   

다음은 DB를 사용할 것인지 그냥 파일을 사용할 것인지를 고려한다.

DB를 사용하면 비용이 발생하기는 하나 안정적이며 로그 검색이나 통계에 훨씬 용이하다.

LOG를 사용하면 구축 비용이 적게 든다. 단, 검색이 매우 어렵다.

최근에는 디스크의 가격이 많이 하락했기 때문에 디스크 가격이 그리 중요하지는 않다.

저장하는 것이 문제가 아니라... 쌓여 있는 데이터를 어떻게 활용하느냐가 관건이기 때문이다.

일단적으로 시스템이라는 관점에서 볼 때, LOG 보다는 DB 사용을 권장하고 싶다.

   

다음은 어떤 DB를 사용할 것인가 이다.

상용 DB라면 오라클이나 MS SQL서버를 가장 많이 사용할 것이고,

비용이 문제라면 mysql을 선택하면 된다.

(무료였으나, 최근 들어 기업용으로 쓸 때는 약간의 가격을 지불하는 것으로 알고 있다.)

   

대부분의 장비들이 syslog를 사용한다면 unix 시스템을 사용하는 것이 편할 것이고,

이 때 가장 저렴하게 구축하는 방법은 PC 서버에 linux+mysql+syslod daemon 조합이다.

여기에 아파치 톰캣등의 웹서버를 이용하여 검색 및 통계 기능을 만들 수 있다.

개발비만 추가하면 된다.(제대로 된 개발자를 찾기 어렵다.)

   

조금 더 제대로 된 시스템을 만들자면...

PC 서버에 windows+mssql+개발프로그램(.net)에 iis 또는 .net 기반의 view를 제공해 주는

시스템을 구축하는 방법도 있을 것이다.

아마도 위의 시스템보다는 더 쉽게 개발자를 구할 있을 것이고

syslog 외에 다른 프로토콜도 쉽게 수용할 수 있을 것이다.

   

또 다른 방법은 mssql 대신 오라클을 사용하는 것이고...

PC 서버 대신 unix 서버(hp, sun, ibm 등)이나 정식 서버를 사용하는 것이다.

마찬가지로 unix 서버를 사용하는 경우에는 syslog daemon을 이용해도 크게 무리는 없지만,

db로 저장하는 부분에 대해서는 프로그램이 필요하다.

그러나 sqlldr 등을 활용하며 대용량 로그에 대한 db insert가 훨씬 용이하고 빠르기 때문에,

개발자 입장에서 볼 때 오라클을 이용하는 것이 훨씬 낫다.

   

실제로 하나씩 insert 하는 것보다...

sqlldr를 이용한 insert가 훨씬 낫다는 것을 테스트 해본 적이 있다.

프로그램으로 초당 수천건의 데이터를 처리해 DB에 저장하는 것은 그리 쉬운 일은 아니다.

   

물론 데이터의 안정성 등에 대해서도 가장 나은 편이다.

단점이야 항상 그렇듯이... 비용이 많이 든다는 것이겠지만...

   

어쨌거나...

쌓여있는 로그에 대한 검색 기능 또한 개발의 중요한 이슈이다.

   

때문에 어떤 검색 기능이나 통계 기능을 원하느냐가

처음에 DB를 설계할 때의 중요한 고려사항이 되기 때문에,

어떻게 보면... 이 부분이 가장 중요한 부분이다.

    

솔루션을 제공하는 업체는 제공할 수 있는 모든 기능을 나열하고,

솔루션을 도입하는 업체는 그 중에 원하는 기능을 골라 도입하지만,

나중에 알고 보면 그 기능은 특정 장비 또는 상황에 국한되어서만 제공할 수 있는 경우가 많다.

때문에 솔루션을 도입할 때는 현재의 운영중인 네트워크 환경에 적용할 수 있는지

확인을 거친 후 도입해야 한다. 쉽지만은 않은 일이다.

 

 

--------------------------

 

 

요약하자면 NMS 에서 장애 관리란

1. 장애 발견 -> 조치 -> 조치에 대한 정보 제공

2. 장애 후 원인발견 -> 로그 관리

3. 장애 예측 -> 장애 징후 -> 성능 또는 로그에 의한 경보

정도로 정리할 수 있다.

   

1번에서 요구되는 것은 장애발생 후 빠른 복구를 위한 조치방법에 대한 정보를 제공할 것인지

2번에서 요구되는 것은 로그에서 원인을 어떻게 찾아낼 것인지,

3번에서 요구되는 것은 성능 또는 로그에서 어떻게 장애징후를 알아낼 수 있는지...

이 세 가지를 충족시키는 것이 knowledge base 일 것이다.

   

knowledge base를 만드는 일은 매우 중요하지만 실제로 만들어내기는 어렵다.

유능한 네트워크 운영자는 NMS라는 시스템과 친하지 않고, 유능한 개발자는 네트워크 장비와 친하지 못한 채 고객의 변덕에 따라 UI 수정작업에 매달리기 때문일 것이다.

또한 자신의 노하우를 정리하여 지식화 하고 이를 제대로 사용하는 풍토가 정착되지 힘든 정서도 한 몫 하여 이러한 KB를 완벽히 제공하는 NMS는 아마도 영원한 숙제로 남게 되지 않을까 싶다.

----------------------------------------------

 

[성능관리]

NMS에서 성능관리라 함은 장애 징후 발견과 장비의 운영 추이를 분석하여

향후 네트워크 설계에 반영하기 위한 운영 데이터의 축적을 의미한다.

   

장애 징후의 발견은 평균 또는 정상 운영에서 발생하는 것 외의 이상 상태를 감지해 내는 것,

그리고 따라서 네트워크 장비를 증설하거나, 회선을 증속 또는 감속하거나, 과잉 투자에 대한 부분을 축소하기 위한 모든 의사결정을 위한 기초 자료 축적 및 자료 제공을 위한 시스템이 필요하다.

   

이 모든 일을 위해서는 일단 현재 운영되고 있는 장비들의 운영정보를 모두 저장하여 적절한 통계 자료를 추출할 수 있는 시스템이 필요할 것이다.

   

장비의 운영 지표 중 주로 요구되는 것은 회선의 증감속을 위한 네트워크 사용량 측정,

그리고 장비 업그레이드 또는 교체를 위한 장비 가용성 측정이다.

   

전자에서 주로 요구되는 것은 회선사용율인데, 회선사용율을 측정하는 방법은 SNMP에서 제공하는 ifinoctets 와 ifoutoctets에 8(byte) 곱한 후 이것을 ifspeed 값으로 나누는 것이다.

예전에 반이중 방식(half duplex)을 사용하던 시절에는 in과 out을 합쳐서 계산했지만,

최근에는 전이중방식(full duplex)을 사용하므로 in과 out를 각각 별도로 산출하는 것이 일반적이다.

   

장비의 가용성 부분은 대부분 cpu와 memory 사용율을 의미한다.

장비에서 처리해야 하는 패킷수와 이를 버퍼링할 수 있는 용량은

장비가 고급화 되어갈수록 점점 더 중요해 지고 있다.

문제는 이 CPU와 memory는 public mib의 영역이 아니라 private 영역이라는 것이다.

벤더마다 모두 다른 값을 다른 방식으로 제공한다.

   

어떤 장비는 cpu 사용율을 어떤 장비는 cpu idle 율을 어떤 장비는 cpu idle time을...

그리고 이러한 값이 아예 제공되지 않는 장비도 있다.

그리고 최근 장비의 진화에 따라 장비당 하나 있던 CPU가 장비당 2개 이상.. 그리고 장비 자체(샤시)외에 모듈에 cpu가 장착되기 때문에, 그리고 여러 개의 장비들이 모여 하나의 장비를 이루는 구조로 변경되는 추세이므로... 원하는 cpu 사용율을 찾아내려면 장비와 그 구조, 해당 모듈의 명칭과 역할 등 해당 벤더에서 제공하는 private mib 구조에 대해 잘 알아야 한다.

메모리도 마찬가지이다. buffer 또는 memory 라는 애매모호한 명칭들로 존재하는 수많은 mib value 중에 해당 장비의 실제 메모리 값을 찾아 적용시켜야 하며, 다시 이를 이를 일반 user가 이해하기 쉬운 사용율로 변환하여 보여 줄 수도 있어야 한다.

이 외에 장비의 특성에 다라 다른 private 항목들을 보는 경우도 있다. L4~ L7 장비의 경우에는 session count도 모니터링하고, 특히 정책에 따라 특정 session에 대한 정보만을 원하는 경우도 있다.

   

"이 장비에서는 어떤 값을 모니터링 해야 하고 그게 snmp에서는 어떤 mib 을 참조하면 됩니다. 

보세요. 장비에서 이 값과 snmp로 보는 이 값이 일치하지요?"

하고 적절한 값을 찾아내고 이를 매치시키고 확인을 해주는 것.

혹은 "이 장비는 유감스럽게도 이러이러한 항목에 대한 value는 snmp로 제공하지 않네요"

라고 확신을 줄 수 있는 사람이 네트워크 업계에 과연 얼마나 될까?

----------------------------

 

 

장애관리에서도 그러했듯이 제일 중요한 것은 무엇을 모니터링할 것인지 결정하는 것이다.

회선사용율, CPU 사용율, 메모리 사용율 이 세 가지를 모니터링하기로 결정했다고 보자.

   

먼저 회선사용율에 대해서 살펴보도록 하자.

앞서 말한 것처럼 회선사용율은 다음과 같은 공식으로 이루어진다.

   

                                                                          Δ(ifinoctets) * 8 *  100

회선송신사용율(output utilization on a interface) = ---------------------------

                                                                          Δ(seconds) * ifspeed 

   

                                                                          Δ(ifoutoctets) * 8 *  100

회선수신사용율(input utilization on a interface) = ---------------------------

                                                                          Δ(seconds) * ifspeed 

   

   

여기서 각각의 mib 정보는 아래와 같다.

   

.1.3.6.1.2.1.2.2.1.10

ifInOctets OBJECTTYPE

−− FROM RFC1213MIB, IFMIB

SYNTAX Counter

MAXACCESS readonly

STATUS Mandatory

DESCRIPTION "The total number of octets received on the interface, including framing characters."

::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib2(1) interfaces(2) ifTable(2) ifEntry(1) 10 }

   

.1.3.6.1.2.1.2.2.1.16

ifOutOctets OBJECTTYPE

−− FROM RFC1213MIB, IFMIB

SYNTAX Counter

MAXACCESS readonly

STATUS Mandatory

DESCRIPTION "The total number of octets transmitted out of the interface, including framing characters."

::= { ISO(1) org(3) DOD(6) Internet(1) mgmt(2) mib2(1) interfaces(2) ifTable(2) ifEntry(1) 16 }

   

.1.3.6.1.2.1.2.2.1.5

ifSpeed OBJECTTYPE

−− FROM RFC1213MIB, IFMIB

SYNTAX Gauge

MAXACCESS readonly

STATUS Mandatory

DESCRIPTION "An estimate of the interface's current bandwidth in bits per second. For interfaces which do not vary in bandwidth or for those where no accurate estimation can be made, this object should contain the nominal bandwidth."

::= { ISO(1) org(3) DOD(6) Internet(1) mgmt(2) mib2(1) interfaces(2) ifTable(2) ifEntry(1) 5 }

   

   

10G 이상의 ifspeed를 지원하는 interface를 측정하는 경우에는 interfaces(2) 아래의 기본 mib이 아니라

ifXObject(?) 아래의 mib들을 이용해야 한다.

   

간혹 ifspeed의 값이 잘못 셋팅되어 있는 경우 사용율이 100%를 훌쩍 넘어가는 경우가 많이 있다.

실제로 업무에 적용했을 대 180% 이상까지도 올라가는 경우도 종종 보았다.

원인은 거의 90% 이상 ifspeed 때문이다.

실제 회선속도(bandwidth)가 알고 있는 속도보다 높은 경우,

장비에 ifspeed가 잘못 셋팅되어 있는 경우 등인데...

전자라면 적은 돈으로 많은 대역을 사용하고 있는 것이니.. 그냥 사용하면 되겠고,

후자라면 장비의 셋팅 값을 바꾸어 주면 된다.

   

NMS 구축 시 이 100%를 넘어가는 값 때문에 운영자들이 NMS를 못믿겠다고 하는 경우가

많이 있었는데... 이는 NMS 문제가 아니라 실제 장비 또는 회선의 문제라고 보는 게 더 맞다고 본다.

또 이런 문제 때문에 100% 가 넘어가면 무조건 100%로 맞추어서 보여달라고 요청하는 관리자도

많이 있었는데... 역시 국내 다른 제품 중에 이렇게 되어 있는 것들을 본 적이 있었다.

   

개인적으로는 보여주기 위해 이렇게 숫자를 맞추는 것보다는...

알고 있는 것과 운영 상태가 다른 것으므로 정보를 수정하는 것이 더 나을 것이라고 생각하고,

그게 NMS의 도입 목적에 더 가깝지 않을까 생각한다.

   

NMS는 네트워크 운영 상태를 파악하고 이를 제대로 운영하기 위한 백데이터를 모아줄 수 있는

시스템이지, 보고서를 작성하기 위해 조작하는 대상이 아니다.

-----------------

 

네트워크의 성능에 대한 관리를 얘기할 때는 이상치에 대한 경고와 평상시의 사용량에 대한 추이 분석에 대한 정보 제공으로 나눌 수 있다. 이상치에 대한 경보 제보 기능은 장애 징후 예보와 밀접한 관계가 있어 보통은 혼동되어 장애 관리에서 사용되어지기도 한다.

   

어쨌거나 현재의 네트워크 상태가 평상시의 사용량과 다르다는 것을 증명하거나, 네트워크 장비들을 증설 혹은 감량을 해야 한다거나 회선을 증속 또는 감속하는 등의 네트워크 운영에 대한 정책을 세울 때 필요한 백데이터들이 바로 이 성능 관리를 위한 데이터들이다.

   

NMS 구축 시 난감한 부분 중 하나가 이 경보 기분을 얼마로 할 것인지, 증속 및 감속을 위한 기준치를 얼마로 할 것인지 결정하는 것이다. 프로젝트를 하다보면 다른 곳(경쟁사)에서는 어떻게 사용하고 있느냐 업체에서 자체적으로 사용하고 있는 기준치는 얼마냐 라는 질문을 받게 되는데 사실 답이 없다.

   

90년대에 네트워크 컨설팅 자료로 많이 쓰여졌다는 모 회사에서 만든 자료라고 하는 달랑 두 장짜리 파워포인트 문서에 보면 아래와 같이 씌여 있다.

(자료근거 : 美 Concord社 Network Health Traffic Guide 4-3 발췌)

=======================

 

 

네트워크 관리 시스템은 말 그대로 네트워크 관리를 위한 시스템이다.

네트워크 관리를 위한 표준 프로토콜이 바로 SNMP이라는 것인데,

1990년대 말까지는 CMIP과 SNMP가 공존하다가 2000에 들어오면서 SNMP의 승리로

귀결지어졌다. 사람들은 복잡한 것을 별로 좋아하지 않는다는 사실이 다시 증명된 셈이랄까..

   

SNMP는 말 그대로 Simple Network Manahement Protocol 이다.

그러나 이 Simple이라는 단어는 항상 상대적으로 라는 수식어가 생략되어 있다는 것을 알아야 한다.

원래 완벽하고 상세하게 설계하기로 했던 CMIP에 비해 상대적으로  Simple 하다는 것일 뿐...

결코 이 프로토콜이 Simple 하다는 것은 아니다...

오히려 구현자가 제멋대로 mib을 결정할 수 있기 때문에 구현자 입장에서는 별로 달갑지 않다.

   

암튼 기본적인 개념상으로 볼 때 이 프로토콜은 매우 Simple 하다.

GET-RESPONSE : 값을 물어본다. 대답한다.

SET : 값을 셋팅한다.

TRAP : 스스로 상태를 보고한다.

이 세 가지 동작을 통해 네트워크를 관리하기로 한 것이니... 매우 Simple 하긴 하다.

   

그럼 방법을 정했으니, 어떤 데이터를 주고 받을 것인가도 알아야 한다.

그 데이터를 정의해 놓은 사전이 MIB(Management information base)이다.

자고로 네트워크 관리자라면 MIB 하면 이게 Man in black이 아니라는 사실을 알아야 겠다.

그리고 이 데이터들을 어떤 식으로 나열해 놓을 것인가를 정의한 것이

SMI(Structure of management information)이다.

   

쉡게 생각해서 SNMP는 언어, MIB은 사전, SMI는 언어규칙이라고 생각하면 된다.

나와 철수가 한국어로 말하고자 한다면...

둘은 일단 한국어로 말할 수 있어야 하며...

상황에 맞는 적절한 단어를 선택하여 정해진 구조(주어+목적어+동사)로 말해야 한다는 것이다.

네트워크 관리 시스템과 네트워크 관리 대상인 장비는

이 SNMP라는 프로토콜로 대화를 하며

SMI에 기반한 MIB에 정의되어 있는 항목을 적절히 선택하여 대화하는 것이다. 

   

때문에 SNMP를 지원하는 장비라고 해서 모두 내가 원하는 대로 관리될 수 있을 것으로

기대해서는 안된다. 예를 들자면 24개월짜리 아가와 대화를 하려면...

분명 한국말로 대화중임에도 불구하고 많은 제약이 뒤따르지 않는가... (아기와의 대화라... --)

네트워크 장비도 이 아가 수준의 장비들이 많이 존재한다고 보면 된다.

   

어쨌건 시장에서는 보다 완벽하고 상세하며 모든 요구사항들을 충족시키는(고자 했던) 

CMIP  대신에 보다 단순하고 구현하기 쉬우며 만들기 쉬운 SNMP를 선택했고...

(벤더 입장에서는 당연히 둘 중 뭘로 할래? 하면.. 쉬운 거.. 로 갈 수 밖에 없다.

개발기간 = 인력 = 돈 = 원가 상승이지 않은가... 사용자측에서도 빨리 되는 제품을 원했고... )

현재는 CORBA니 뭐니 하는 별종이 등장하고 있지만...

   

결국에는 현재 NMS에 주로 사용되는 주요 프로토콜은 SNMP라는 사실이 중요하다.

   

여기에 SNMP의 한계를 극복하기 위해 추가적으로 등장한 것이

RMON(Remote network MONitoring)이라는 프로토콜이다.

이름만 봐서는 무슨 용도인지 참 상상하기 어려운 용어인데...

이름대로 풀어보자면 멀리서 네트워크의 사용량을 감시하기 위한 프로토콜이다. ^^;;

즉 SNMP로 커버하기 힘든 멀리 떨어져 있는 특정 로컬 네트워크 영역(segment)에서의

네트워크 사용량(구조)을 알아보고자 하는 의도에서 시작되었으며,

SNMP와 유사한 구조로 MIB이라는 것을 채택하였다.

따라서 RMON I, II에서 정의한 MIB들이 존재하게 되었으며, 

RMON Probe 들은 이 RMON MIB을 지원하고,

대부분의 SNMP Manager에서 이 RMON MIB을 이용하여 해석할 수 있는 구조이다.

   

그러나 이 RMON이라는 것이 참 문제가 많았다.

여기서 필요한 데이터라는 것이 관리자들이 궁금해 하는 것들을 많이도 제공해주기는 했는데,

결정적으로 이러한 데이터들은 대단히 양이 많았고, 처리하는데 시간이 많이 걸린다는 것이었다.

따라서 RMON 정보들을 처리하기 위한 프로브들은 대량의 데이터를 보관, 처리해야 했고,

당시 저용량의 네트워크 장비들은 이러한 것들을 수용하기 힘들 수 밖에 없었다.

2000대 초반 장비들의 스펙들을 보면 RMON 지원이라는 항목들을 많이 볼 수 있는데,

엔지니어들은 이를 올리는 것을 대단히 꺼려하였다.

장비가 부하를 견디지 못해 죽어버리는 일이 종종 발생했기 때문이다.

특히 네트워크가 TCP/IP로 바뀌고, 네트워크의 데이터량이 증가하고,

전송속도가 10/100에서 1G/10G로 가는 현 시점에서 장비가 이런 데이터들을 수용하고 처리하는 것은 거의 재난에 가까운 일이었다. 때문에 현재는 일부 RMON 프로브만 남고 대부분 시장에서 사라진 상태다.

   

그러나 네트워크에 흘러다니는 데이터의 정체를 알고 싶다는 꾸준한  요구가 있었고,

이런 이유로 인해 최근에(2000년도 초반) 등장한 것이 netflow로 잘 알려진 nFlow 라는 개념이다.

   

본래 이 라우터, 스위치 등 네트워크 장비란 놈이 패킷 기반으로 동작을 한다.

즉 송신자가 발송한 정해진 사이즈의 패킷을 정해진 경로를 통해 수신자에게 잘 보내면 되는 것이 네트워크 장비의 역할인데... 이 패킷은 어떤 어플리케이션의 조각 또는 데이터의 조각이므로 실제로는 하나의 업무 Flow가 원활하게 이 정해진 경로를 타고 수행되는 것이 궁극적인 목표가 된다는 데 촛점을 맞춘 개념이다.

   

따라서 패킷과 경로라는 컨셉 기반의 라우터들이... 이 Flow 컨셉을 차용하여 장비에 적용하면서

그 동안 RMON에서 관리자들이 가장 궁금해 하던 부분만 떼어내어 관리용으로 제공하기로 한 것이다.

   

이 flow 라는 표준은 7개의 장비 제조 벤더들이 모여서 만들었기 때문에 RFC 어쩌고 하는 문서들이 없다. 대신 업체들이 동의한 규약은 있다. 큰 그림만 만들고 구현은 벤더 나름대로 했기 때문에 내용도 조금씩 다르다는 말이다. 

   

어찌되었건 중요한 것은 이 flow 표준을 따르는 장비들은 flow에 대한 정보들 -  ip, port(어플리케이션 구분 가능), 수신지 ip, port, 패킷량 등을 제공한다는 것이다.

네트워크 사용자들이 많이 궁금해 하는 것 중에 하나가 90% 이상 꽉꽉 차서 흘러다니는 저 회선에 실제 돌아다니는 패킷의 정체가 무엇이냐? 인데... 바로 이것을 해결해 준 것이다.

   

CISCO에서 사용하는 용어가 netflow이며..  flow의 대명사처럼 사용된다.

업체에 따라 c-flow, s-flow 등의 이름을 붙이기도 한다.

   

물론 RMON이 그것을 제공해 주기는 했지만....

엄청난 데이터의 발생으로 인한 여러 가지 문제를 극복하지 못했으므로...

flow를 통해서 그것을 제공해 주기로 한 것은 획기적인 일이 아닐 수 없었다.

   

처음에는 rmon이 그러했듯이.. flow 기능에도 여러 가지 문제들이 많이 있었지만...

지금은 cisco를 필두로... 많이 개선되어... 이를 기반으로 한 nms 제품들이 많이 나와 있다.

   

물론 이것도 만능은 아니며, 여전히 대용량 데이터에 대한 처리부분이 한계로 남아 있다.

cisco는 이것을 독립모듈로 떼어내어 NAM이라는 모듈로 제공하고 있다.  


<http://blog.daum.net/_blog/hdn/ArticleContentsView.do?blogid=05LLi&articleno=6818685&looping=0&longOpen=>에서 삽입

반응형

Unix Domain Socket - UDP

윤 상배

dreamyun@yahoo.co.kr

   

   

1절. 소개

우리는 이미 이전에 Unix Domain Socket를 이용한 IPC 에서 Unix Domain Socket 에 대한 기본적인 내용을 다루었었다.

그때는 SOCK_STREAM 을 이용한 연결지향의 Socket 를 사용했었는데, internet 소켓과 마찬가지로 UDP 특성 Socket 를 사용할수도 있다. 이번 글 에서는 UDP 를 이용한 Unix Domain Socket 에 대해서 알아보도록 하겠다.

   

2절. Unix Domain Socket (UDP)

2.1절. 특징

internet socket 상에서 UDP 를 다룰때, 관심을 가지는 특성이 비연결지향성이며, 그런이유로 데이타를 유실할수도 있으며, 데이타의 순서가 바뀔수 있다. 그러므로 중요 데이타 통신을 위한 프로토콜로는 UDP 가 적합하지 않다. 라는 점이 될것이다.

그러나 Unix Domain 영역의 UDP 는 internet 영역과는 특성이 좀 다르다고 할수 있다. Unix Domain 에서의 UDP 는 일종의 PIPE 와 같은 형태로 다루어진다. 게다가 동일한 같은 시스템 영역에서의 데이타 교환이므로 패킷이 유실되거나, 순서가 뒤바뀌는 등의 문제는 전혀 발생하지 않을거라고 장담할수 있다.

   

2.2절. 메시지 전달 방식

internet socket 에 전달되는 패킷들이 헤더 + 바디 로 이루어지는 것과 마찬가지로, Domain 영역에서의 데이타도 헤더 + 바디 로 이루어진다. 그러나 헤더의 구성요소는 매우 다르다.

Domain 영역에서의 데이타 통신은 알겠지만 "지정된 파일" 을 통해서 이루어지게 된다. 이 파일로 데이타를 쓰고/읽는 작업을 하며, 이것은 마치 FIFO 와 같은 pipe 형태로 전달된다.

그러므로 헤더영역에는 다른 기타의 정보가 들어가는게 아닌 통신을 위한 파일정보 가 들어가게 된다. /usr/include/sys/un.h 의 sockaddr_un 구조체를 보면 확실히 이해가 가능할 것이다.

struct sockaddr_un
{
__SOCKADDR_COMMON (sun_);
char sun_path[108]; /* Path name. */
};
                        

위의 구조체를 보면, sockaddr_in 과는 달리 단지 파일의 위치 지정을 위한 108바이트 크기의 배열변수만 있는것을 알수 있다.

   

2.3절. 서버/클라이언트 구성방식

internet socket 을 이용한 서버/클라이언트 구성과는 달리 Domain 영역에서 udp 를 이용한 서버/클라이언트의 구성은 주의해야 될 몇가지 점이 있다.

가장 기본적인 문제는 Domain 영역에서의 udp 는 Internet 영역에서의 udp 와는 달리 경로를 지정 할수 없다는 단점을 가진다. 이것은 다중의 클라이언트를 받아들이는 서버의 경우 문제가 될수 있다.

다음은 Internet 영역의 udp 서버/클라이언트 모델의 경우이다.

+----------+
+------- | Client 1 | address 1
| +----------+
+------+ | +----------+
| 서버 |-+------- | Client 2 | address 2
+------+ | +----------+
| +----------+
+------- | Client 3 | address 3
+----------+
                        

Internet 영역에서의 서버는 단지 하나의 소켓지정번호(endpoint) 만을 가지고도 다중의 클라이언트와의 연결이 가능하다. 그 이유는 Internet 영역에서 통신을 할때 UDPIP 상위 프로토콜이므로 IP 프로토콜의 헤더를 통해서 해당 메시지가 어디에서 출발했는지 알수 있기 때문이다. 그러므로 굳이 select(2) 나 poll(2) 같은 작업없이 단지 하나의 소켓지정번호로 통신이 가능해진다.( UDP 프로그래밍의 기초를 참고하라.)

그러나 Unix Domain 영역의 udp 소켓이라면 이야기가 달라진다. 기본적으로 가질수 있는 정보가 "파일 경로" 뿐이므로 다중의 클라이 언트로 부터 메시지를 받았을때 어떤 클라이언트로 부터 메시지가 전달되었는지를 알수가 없는 것이다. 물론 이것은 데이타 영역에 클라이언트를 식별할수 있는 어떤 정보를 보냄으로써 해결할수 있긴 하겠지만, 설사 그렇다 하더라도 서버는 다중의 클라이언트중 원하는 클라이언트(client)로 메시지를 보낼방법이 없다. 만약 다중의 클라이언 트가 떠있는 상태에서 메시지를 보낸다면 누가 먼저 읽을지 예측할수가 없게된다.

이문제를 해결하기 위해서는 각 클라이언트 마다 통신을 위한 각각의 소켓지정파일 을 생성할수밖에 없다. 이것은 FIFO 에서 서버/다중클라이언트 를 구성하기 위한 방법과 마찬가지이다.

+----------+
+---| Client 1 |
+------+ | +----------+
| |-----+ +----------+
| 서버 |---------| Client 2 |
| |-----+ +----------+
+------+ | +----------+
+---| Client 3 |
+----------+
                        

결국에는 Domain 영역에서 udp 소켓을 사용하기 위해서는 select, poll 등을 써야만 한다는 결론에 도달한다.

여기에서 한가지 궁금한점이 문득 생길것이다. Domain 영역 UDP 소켓 에서의 다중클라이언트를 받아들이기 위한 서버의 제작을 위해서는 그럼 클라이언트의 숫자만큼 소켓파일을 생성시켜야한다는 뜻인데, 그렇다면 서버는 어떻게 클라이언트가 접근할줄 알고 클라이언트와 서버 모두가 알수 있는 소켓파일을 생성할것인가 ?

이문제의 해결방법은 여러가지가 될것이다. 마치 internet 의 TCP 소켓이 다중의 연결을 받아들이기 위해서 accept(2) 하는 하나의 endpoint 소켓을 두는 것처럼, Domain 영역에서도 하나의 endpoint 파일을 두는 것이다. 물론 이 endpoint 파일의 이름은 서버와 클라이언트간에 약속이 되어 있어야 할것이다.

그러먼 서버는 최초에 endpoint 를 위한 소켓파일을 하나 생성하고 이것을 통해서 클라이언트가 접근하면 적당한 이름으로 새로운 소켓파일을 만든다음에 이 파일이름을 클라이언트에게 전달해서 클라이언트가 전달받은 파일이름으로 쓰기를 하도록 하면 된다.

   

2.3.1절. 예상과는 달리 사용하는게 좀 번거롭군요 ?

예상과는 달리 다중의 클라이언트를 받아들이도록 Domain 영역 udp 소켓을 구성하는게 좀 까다롭다라는 생각이 들수도 있을 것이다.

그러나 어차피 내부 시스템에서의 통신용이라면 대부분의 경우 여러개의 클라이언트가 붙는다고 하더라도, 그 클라이언트가 정해져 있는 경우가 대부분이다. 그러므로 그냥 각 클라이언트 마다 어떤 파일을 통신에 쓰라고 아예 지정해주면 된다. 그러면 단지 select 나 poll 만을 돌림으로써, 간단하게 서버/클라이언트 프로그래밍이 가능하다.

또한 Domain 영역에서의 TCP 소켓과는 달리 다소 복잡한 연결과 연결대기를 위한 작업이 필요가 없으므로 코딩하기도 간편하다는 장점도 가지고 있다. 또한 패킷단위로 주고 받음으로 직관적으로 이해하기 쉬운 코드를 만들수 있다는 장점도 가진다.

   

2.4절. 예제 코드

그럼 예제 프로그램을 만들어 보도록 하겠다. UDP 프로그래밍의 기초 에서 다루었던 덧셈 프로그램인 sum_server.c 와 sum_client.c 를 Domain 영역에서 동작하도록 변경시킬 것이다. 위의 프로그램들을 참조하면서 코딩하도록 하자.

프로그램자체는 일반적인 Internet UDP 소켓 프로그램과 거의 동일함으로 이해하는데 이해가 없을것이다.

   

2.4.1절. 서버프로그램

예제 : sum_server.c

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

struct data
{
int a;
int b;
int sum;
};
int main(int argc, char **argv)
{
int sockfd;
int clilen;
struct data mydata;
struct sockaddr_un clientaddr, serveraddr;

sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("socket error : ");
exit(0);
}
unlink(argv[1]);

bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, argv[1]);

if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
{
perror("bind error : ");
exit(0);
}
clilen = sizeof(clientaddr);

while(1)
{
recvfrom(sockfd, (void *)&mydata, sizeof(mydata), 0, (struct sockaddr *)&clientaddr, &clilen);
printf("%d + %d = %d\n", mydata.a, mydata.b, mydata.a + mydata.b);
sendto(sockfd, (void *)&mydata, sizeof(mydata), 0, (struct sockaddr *)&clientaddr, clilen);
}
close(sockfd);
exit(0);
}
                                

   

2.4.2절. 클라이언트 프로그램

예제 : sum_client.c


// 클라이언트 아래와 같이 하면 안됩니다.
// 서버에서 보낼 때, 클라이언트가 바인드해야 정보를 받을 수 있습니다.
// 이 글을 보시는 분은 적절한 코드로 수정해 주시기 바랍니다.
// 그외 기타 간단한 오타 및 타입 오류는 제가 수정하고 갑니다. - 용운

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

struct data
{
int a;
int b;
int sum;
};
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_un serveraddr;
int clilen;
struct data mydata;

sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("exit : ");
exit(0);
}

bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, argv[1]);
clilen = sizeof(serveraddr);

mydata.a = atoi(argv[2]);
mydata.b = atoi(argv[3]);
mydata.sum =0;

if (sendto(sockfd, (void *)&mydata, sizeof(mydata), 0,
(struct sockaddr *)&serveraddr, clilen) < 0)
{
perror("send error : ");
exit(0);
}
if (recvfrom(sockfd, (void *)&mydata, sizeof(mydata), 0,
(struct sockaddr *)&serveraddr, (socklen_t *)&clilen) < 0)
{
perror("recv error : ");
exit(0);
}
printf("result is : %d\n", mydata.sum);

close(sockfd);
exit(0);
}
                                

   

2.4.3절. 테스트

먼저 서버를 띄운다음에, 클라이언트를 통해서 더하고 싶은 2개의 숫자를 인자를 통해서 넘기면 된다.

[root@localhost src]# ./unix_domain_udp_server /tmp/test_udp
5 + 6 = 11
7 + 1024 = 1031
...
                                

[root@localhost src]# ./unix_domain_udp_client /tmp/test_udp 5 6
[root@localhost src]# ./unix_domain_udp_client /tmp/test_udp 7 1024
                                

   

3절. 결론

다른 Domain 영역 소켓과 마찬가지로, IPC 대용으로 사용가능하다. TCP 소켓이 IPC 대용으로 사용하기가 비교적 복잡하다는 단점과, 오늘 알아본 UDP 도메인 소켓과 아주 비슷한 FIFO 가 범용성이 좀더 떨어지는 단점을 보완한 적당하고 편리하게 사용가능한 IPC 로써의 용도를 제공해 줄것이다.

   [출처]<http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/system_programing/IPC/Unix_Domain_Socket_UDP>에서 삽입

반응형

다차원 배열을 1차원 배열로 변경하고자 할 때

Programming/C / 2009/08/31 15:53

1. 2차원 배열

a[IMAX][JMAX]

b[IMAX*JMAX]

b[i*JMAX+j] = a[i][j]

   

2. 3차원 배열

a[IMAX][JMAX][KMAX]

b[IMAX*JMAX*KMAX]

b[i*JMAX*KMAX+j*KMAX+k]=a[i][j][k]

   

<http://revoman.nudecode.org/entry/다차원-배열을-1차원-배열로-변경하고자-->에서 삽입

반응형

'Language > C' 카테고리의 다른 글

popen 함수 pclose 함수 예제  (6) 2012.07.06
pipe 함수 예제  (14) 2012.07.06
C언어 - 스트림(Stream)이란?  (6) 2011.08.11
리눅스 시스템 프로그래밍 8장 IPC  (6) 2011.08.11
call by value와 call by reference | KLDP  (6) 2011.08.11

MSG QUEUE SIZE 확인

Unix & Linux/Command-Utility / 2008/04/03 19:54

PARAMETER

MSGMNB: Maximum number of bytes per message queue.

MSGMNI: Maximum number of message queue identifiers (system wide).

MSGSEG : Maximum number of message segments per queue.

MSGSSZ : Size of a message segment.

MSGTQL : Maximum number of messages (system wide).

MSGMAX: Maximum size of a whole message. On some systems you may need to increase this limit.

                 On other systems, you may not be able to change it.

   

   

UNIX OS 에서 확인하기

  • SOLARIS

sysdef  -i | grep MSG

   

  • HP-UX

kmtune | grep msg

   

  • LINUX

cat /proc/sys/kernel/msgmax

cat /proc/sys/kernel/msgmnb

cat /proc/sys/kernel/msgmni

   

또는 sysctl 명령어를 사용할 수 있다.

   

  • sysctl option
           -n     Use this option to disable printing of the key name when printing values.

           -e     Use this option to ignore errors about unknown keys.

           -N     Use  this  option  to  only  print the names. It may be useful with shells that have pro-
                  grammable completion.

           -q     Use this option to not display the values set to stdout.

           -w     Use this option when you want to change a sysctl setting.

           -p     Load in sysctl settings from the file specified or /etc/sysctl.conf if none given.  Spec-
                  ifying - as filename means reading data from standard input.

           -a     Display all values currently available.

           -A     Display all values currently available in table form.

    EXAMPLES
           /sbin/sysctl -a

           /sbin/sysctl -n kernel.hostname

           /sbin/sysctl -w kernel.domainname="example.com"

           /sbin/sysctl -p /etc/sysctl.conf

IPC관련 Kernel Tunable Parameter 설정

Solaris

/etc/system 에 예를 들어 다음과 같이 kernel tunnable parameter를 설정하여 쓸수 있습니다.

#

#

set pt_cnt=256

set npty=256

   

set msgsys:msginfo_msgmap = 1000

set msgsys:msginfo_msgmax = 8192

set msgsys:msginfo_msgmnb = 1048576

set msgsys:msginfo_msgmni = 200

set msgsys:msginfo_msgssz = 400

set msgsys:msginfo_msgtql = 8192

set msgsys:msginfo_msgseg = 4096

   

set shmsys:shminfo_shmmax = 4294967296

set shmsys:shminfo_shmmni = 100

set shmsys:shminfo_shmseg = 32

시스템의 /etc/system을 확인해보시고, 설정이 안되어 있는 경우 설정 후 재부팅하여 장비를 재기동시켜 적용하시기 바랍니다.

   

참고: Solaris Kernel Tunable Parameter - IPC 관련

parameter | Default | Description

-----------------------------------------------------------------------

msginfo_msgmap | 100 | messages map안의 항들의 수

msginfo_msgmax | 2048 | 최대 message 크기

msginfo_msgmnb | 4096 | queue의 최대 bytes

msginfo_msgmni | 50 | mesaage queue identifers의 수

msginfo_msgssz | 8 | 한 messages의 segment 크기

msginfo_msgtql | 40 | system messages headers의 수

msginfo_msgseq | 1024 | messages segments의 수( ?<32768 )

-----------------------------------------------------------------------

seminfo_semmap | 10 | semphore map의 항들의 수

seminfo_semmni | 10 | semphore identiers의 수

seminfo_semmns | 60 | system상에 semphores의 수

seminfo_semmnu | 30 | system상에 undo structures의 수

seminfo_semmsl | 25 | id마다 semaphores의 최대 수

seminfo_semopm | 10 | semphore call마다 연산들의 최대 수

seminfo_semume | 10 | process당 undo entries의 최대 수

seminfo_semvmx | 32767 | semphore 최대값

seminfo_semaem | 16384 | maximum value for adjustment on exit

----------------------------------------------------------------------

shminfo_shmmax | 1048576 | maximum shared memory segment size

shminfo_shmmin | 1 | minimum shared memory segment size

shminfo_shmmni | 100 | shared memory identifiers의 수

shminfo_shmseg | 6 | process당 segments

-----------------------------------------------------------------------

HPUX(Tandem)

- NonStop-UX tandem 4.2MP C52IPM10.puma.0326.20:29 S4000 mips

- idtune 명령으로 kenerl 파라메터 조정 (root만 수행가능)

# /etc/conf/bin/idtune -g MSGMAX

16384 8192 512 131072

(cur) (def) (min) (max)

# /etc/conf/bin/idtune -g MSGMNB

16384 16384 4096 6291456

(cur) (def) (min) (max)

HPUX(C449)

- HP-UX dncp1 B.11.00 E 9000/888 2140000971 8-user license

- kmtune 명령으로 kernel 파라메터 조정

Parameter: msgmax

Value: 8192

Default: 8192

Parameter: msgmnb

Value: 65536

Default: 16384

HPUX(rp7420)

- HP-UX hahlr1 B.11.23 U 9000/800 3333801845 unlimited-user license

- kctune 명령으로 kernel 파라메터 조정

hahlr@hahlr1:/etc:232 % kctune msgmax

Tunable Value Expression Changes

msgmax 8192 Default Immed

hahlr@hahlr1:/etc:235 % kctune msgmnb

Tunable Value Expression Changes

msgmnb 1048576 1048576 Immed

Linux

현재 Message Queue 사이즈

#> sysctl -a | grep kernel.msg

   

kernel.msgmax = 8192

kernel.msgmni = 16

kernel.msgmnb = 16384

Message Queue 사이즈 변경

#> sysctl -w kernel.msgmni=1024

#> sysctl -w kernel.msgmnb=1048576

설정파일에 저장

vi /etc/sysctl.conf => 새 설정값 저장

kernel.msgmni=1024

kernel.msgmnb=1048576

   

   

   

   

   출처

<http://revoman.nudecode.org/110#comment8832056>에서 삽입

반응형

'Linux' 카테고리의 다른 글

NMS의 기본 개념 - 장애관리  (4) 2011.08.23
Unix Domain Socket UDP  (4) 2011.08.19
[명령어]OS 별 CPU, Memory, 커널Bit 확인방법  (11) 2011.08.11
RAID  (3) 2011.08.11
SNMP란 무엇인가요?  (3) 2011.08.11

(카아알) Karl's the story of a proper life.

C언어 - 스트림(Stream)이란?

2009/04/21 11:02 in I'm Developer.

스트림이란 일련의 문자열이며, C언어에서 자료를 입출력하기 위하여 사용하는 것으로

프로그램과 입출력 장치 사이에서 입출력 자료들을 중계하는 역할을 담당합니다.

   

스트림(Stream)이란 글자 그대로 해석하자면 '흐름', '흐르다'라는 뜻으로,

데이터를 입력 받거나 출력하려면 먼저 스트림에 일련의 바이트 문자들을 기록한 다음

스트림으로부터 데이터를 읽거나 특정 장치에 데이터를 출력하는 것입니다.

스트림의 장점

  

프로그램의 입출력 동작이 입출력 장치와는 독립적이기 때문에, 스트림이 어디로 가는지

어디에서 오는지에 대해 신경 쓸 필요가 없습니다.

  

즉, 프로그램 작성시 입출력 장치의 종류에 따라 다르게 프로그램을 작성할 필요없이

스트림을 통하여 입출력 하도록 프로그램을 작성하면, C라이브러리 함수와 운영체제에 의하여

자동으로 원하는 장치에 입출력 됩니다.

     

   

   

표준 스트림

  

C언어가 제공하고 있는 표준 입출력 스트림은 다음과 같습니다.

스트림

설명

장치

stdin

표준 입력

키보드

stdout

표준 출력

화면

stderr

표준 에러

화면

stdprn

표준 프린터

프린터

stdaux

표준 보조

직렬포트

 

  

스트림은 C프로그램이 실행될 때 자동으로 열리고 프로그램 종료될 때 자동으로

닫히기 때문에 프로그램을 위한 특별한 조치가 필요 없습니다.

스트림의 종류

  

스트림의 종류에는 텍스트 스트림과 바이너리 스트림이 있습니다.

  

텍스트 스트림

바이너리 스트림

텍스트 문자만을 처리

   

(예) 표준 입출력 스트림

자료를 바이트 단위로 처리하기

때문에 텍스트 문자뿐만 아니라

모든 종류의 데이터를 처리

(예) 파일을 사용한 입출력

 

반응형

+ Recent posts