Skip to content
 

리눅스 데몬 개발 1/8

리눅스에서 TCP/IP 데몬 개발을 단계적으로 설명하고자 한다.

총 8단계에 걸쳐서 연재를 할 예정이고 각 단계별로 간단한 소스와 설명을 통해서 데몬 프로그램 기법을 정리할 예정이다.

모든 단계별 소스는 아주 간단하게 동작하도록 작성하였으나 보고 이해하기만 하면 절대로 그 의미를 100% 자신의 것으로 만들 수 없다. 앞으로 나오는 8단계는 영어 알파벳이라 생각하고 완젼히 외워야 한다. 복사해서 실행하지 말고 직접 타이핑 쳐서 컴파일 하기 바란다.

1단계 : fork()
2단계 : signal()
3단계 : thread
4단계 : 간단한 tcp 서버 데몬 #1
5단계 : 간단한 tcp 서버 데몬 #2
6단계 : 복수 클라이언트 접속용 tcp 서버 데몬 #1
7단계 : 복수 클라이언트 접속용 tcp 서버 데몬 #2
8단계 : 복수 클라이언트 접속용 tcp 서버 데몬 #3

물론 8단계가 완벽한 데몬형태가 되지는 않지만 8단계의 모든 소스를 조합한다면 충분히 완벽한 데몬을 제작하는데 어렵지 않을것이다.

1단계 : fork()

대부분의 네트웍 데몬을 공부하게 되면 가장 먼저 이해해야 하는 함수가 fork()다. 이 함수는 child processor를 생성하는 함수로 간단한 셈플을 아래 작성했다.

아래의 프로그램을 실행하면 재미있는 결과가 나올것이다.

물론 결과에서 프로세서 아이디에 해당하는 숫자(31332,31332) 는 실행하는 컴퓨터에 따라서 다르게 표시될것이다.

프로세서를 이해하지 못하는 사람이라면 if문으로 싸여진 출력문 중에서 조건이 맞는 하나만 출력되리라 생각되지만 실제로 실행결과는 두가지 모두 출력하게 된다.

하지만 fork() 위로는 출력문은 하나만 출력된다.
이는 fork() 가 호출되기 직전까지는 하나의 프로세서에서 fork()를 만나면서 두개의 프로세서로 나뉘어진다는 의미다.
손오공이 분신술로 2마리가 되는것과 같다.(^^)

fork()는 불려지는 순간 호출한 프로세서를 복제하게 되고 그 이후는 각각 따로 동작하게 된다는 점이 중요하다.

그래서 cnt값을 출격하는것이 Parent와 Child가 다르게 찍히게 되는것이다. Sleep이라는 함수를 이용해서 약간의 시간차 출력문으로 cnt의 변화값을 출력하게 되는데 초기 10의 값은 두 프로세서가 동일하게 가지고 있지만 부모프로세서는 중간에 0으로 변경을 하게 되어 마지막에 프로그램이 종료하는 순간 출력문은 10, 0 두가지 모두 출력하게 되는 것이다. 프로세서 번호를 따져보면 Parent와 Child가 초기에 같은 변수가 각각 따로 변함을 알게 된다.

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h>  

void main( int argc, char *argv[] ) 
{ 
        int      cnt = 10; 
        pid_t   pid;  

        printf( "Call fork() 
" );  

        pid = fork();  

        printf( "fork() : %d 
", pid );  

        if ( pid )      // parent 
        { 
                cnt = 0; 
                printf( "This is parent : %d 
", getpid() ); 
                sleep( 5 ); 
                printf( "server end 
" ); 
        } 
        else 
        { 
                printf( "This is child : %d, %d 
", getpid(), getppid() ); 
                sleep( 3 ); 
                printf( "child end 
" ); 
        }  

        printf( "End process : %d %d 
", getpid(), cnt ); 
}

=======================================
Call fork()
fork() : 31332
fork() : 0
This is child : 31332, 31331
This is parent : 31331
child end
End process : 31332 10
server end
End process : 31331 0
======================================

3 Comments

Leave a Reply