[42Seoul] - Minitalk (Main)

Joey·2022년 6월 22일
0

42 SEOUL

목록 보기
2/20
post-thumbnail

1.만들어야 하는것

Server와 Client의 프로그램을 두개 만들어 Unix Signal로 통신하게 만들기


2.Unix Signal이란?

  • Signal이란 Software interrupt**로, process에 무엇인가 발생했음을 알리는 간단한 메시지를 ‘비동기'적으로 보내는 것이다.
  • Signal을 받은 프로세스는 Signal에 따른 미리 지정된 기본동적을 수행할 수도 있고, 사용자가 미리 정의해 놓은 함수에 의해서 무시하거나, 특별한 처리를 할 수 있다.
  • 예를 들어 프로세스가 진행중에 Ctrl +c 를 누른다거나, 프로세스에 kill 명령이 내려지는 것이 발생했을 때 Signal이 발생한다.

💡 **interrupt : CPU의 정상적인 프로그램 실행을 방해하는 것

그러므로 우리는 Signal을 이용하여 신호를 보내고 받도록 만들어주면 된다.


3.사용 가능한 함수

  • 과제에서 쓸수 있는 함수들이 주어져 있었다. 아래의 함수들을 통해 구현을 할 수 있다. 아래에 나열된 함수 외에도 subject에 몇개의 함수가 더 있으니 참고하면 된다.
    Server 프로그램 : 이 함수 중에서 Signal과 Sigaction를 이용 함으로써 Signal을 받았을 때 어떤 행동을 할지 결정을 할 수가 있다.
    Client 프로그램 : Kill함수를 이용하여 Client에서 Server로 신호를 보내줄수 있다.
  • Process 진행 ----------> 시그널 발생(kill함수, Client프로그램) ---------> 미리 정해진 행동을 수행함.(signal/sigaction, Server프로그램, 비동기적으로 작동함)

-.signal

: 성공하면 handler 함수를 실행, 실패하면 -1을 리턴

void (*signal(int signum, void (*handler)(int)))(int);

-.sigaction

: signal로 할 수 있는 기능들에 제한이 있어, sigaction으로 추가적인 기능들을 수행할 수 있다
아래에 각 기능들 나열함.

struct sigaction{
	void		(*sa_handler)(int);
        void		(*sa_sigaction)(int, siginfo_t *, void *);
        sigset_t	sa_mask;
        int		sa_flags;
        void		(*sa_restorer)(void);
};

1)sa_handler

핸들러 함수에 대한 포인터, 기존 signal 함수에서 사용하던 핸들러 함수와 같다.

2)sa_sigaction

: 뒤에 나오는 sa_flags에 SIGINFO를 넣으면 사용할수 있으며,
기존 sa_handler의 기능에 추가하여 client에서 오는 정보, 그리고 이전에 실행한 sigaction에 대한 정보를 가져올수 있다.
(과제에서는 이전 sigaction정보는 그다지 필요하지 않다.)

3)siginfo_t *

: 시그널을 보낸쪽에 대한 정보를 확인할 수 있다.

4)sa_mask

: Sigaction은 특정 시그널들을 Block 할 수도 있다. Signal을 Block할지 말지를 설정 하는 곳이다.
(이 과제에서는 특별히 Signal Block을 할 필요는 없었다. 하지만 기본 Setting은 필요하다.)

5)sa_flags

: 위에서 설명한대로, sa_sigaction 핸들러를 사용하기 위해선 여기에 SIGINFO를 넣어야 한다. 넣지 않으면 sa_handler를 사용하는 것이다. 결론적으로 (sa_handler나 sa_sigaction 중 하나를 사용한다고 생각하면 된다.)

6)sigaction의 void *

: 이전 sigaction에 대한 정보가 담김

	struct sigaction	act; //sigaction의 구조체를 만든다.
	
    act.sa_sigaction = act_handler;  //signal이 들어왔을때 실행할 함수를 만든다.
	act.sa_flags = SIGINFO; //sa_handler가 아닌 sa_sigaction을 사용하기 위한 셋팅값
	sigemptyset(&(act.sa_mask)); //sa_mask를 사용하지 않기 때문에 비워준다.(기본 셋팅)

-.pause

signal이 들어오면 어떻게 할지 셋팅을 한 뒤에 signal을 대기하게끔 만들어주면 된다.
이에 따라 signal을 받을 수 있게 대기상태를 만들어 주는 함수이다.

	//server 영역
	while (1)
	{		
		sigaction(SIGUSR1, &act, NULL); 
        #SIGUSR1이 들어왔을때 미리 셋팅한 sigaction인 act로 들어간다, 세번째 인자는 이전의 sigaction정보이다.
		sigaction(SIGUSR2, &act, NULL);
        #SIGUSR2이 들어왔을때 미리 셋팅한 sigaction인 act로 들어간다, 세번째 인자는 이전의 sigaction정보이다.
		pause(); 
        #signal이 들어오게 대기하게 함.
	}

-.kill

	int kill(pid_t pid, int sig); //kill을 성공하면 0을, 실패하면 -1을 리턴하게 된다.

4.Bonus구현

: Bonus구현을 위해서 두가지를 구현해야 하는데, 하나는 유니코드에 대한 구현이고 다른 하나는 Client에서 메세지를 보내고 Server가 다 받았으면 이를 다 받았다고 수신확인을 해주는 기능이다.

-.유니코드 구현

: 이번에 처음 알게 되었는데 유니코드가 1~4byte로 이루어졌는데, 앞에 오는 4bit로 이 길이가 결정된다는 것이었다.

U+0000~U+007F : UTF-8 Encoding 0xxx xxxx 8bit (총 1byte)
U+0080~U+07FF : UTF-8 Encoding 110x xxxx 10xx xxxx 16bit (총 2byte)
U+0800~U+7FFF : UTF-8 Encoding 1110 xxxx 110x xxxx 10xx xxxx 24bit (총 3byte)
U+10000~U+10FFFF : UTF-8 Encoding 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx 32bit (총 4byte)

그래서 이 앞의 4bit에 따라서 얼마나 받을지 결정을 해주면 된다.
예를 들어 한글 '가'를 보내면 3byte의 data를 보내줘야 '가'를 상대쪽에서 출력을 할수가 있다.

유니코드를 검색을 해보면 '가'를 표현하기 위해서는 위와 같이 234, 176, 128을 보내야 저 글자를 표현할 수 있다. 이를 이용해서 Server프로그램에서 조합을 하면 출력이 가능하였다.


-.수신확인

: 두번째 보너스 요구사항은 수신확인이다. 의외로 이 부분은 쉽게 넘어갈수가 있다. 우리가 그냥 문자만 보내면 서버는 계속 문자를 받을수가 있다. 하지만 문장의 끝은 어떻게 확인을 할 것인가? 이는 여러 방법이 있겠지만 나의 경우 쓰지 않는 127을 보내주었다.

man ascii에서 보면 우리는 출력을 하지 못하는 코드들이 꽤 많았었다. 이 중 나는 127을 골라서 만약 127이 들어온다면 마지막으로 인식하고 Client프로그램에 메세지를 다 받았다고 확인을 해주었다.

127말고도 출력을 하지 못하는 코드들을 골라서 해도 별 이상없이 작동함을 확인하였다.


5.회고

: minitalk를 시작하면서 이 과제에 대한 스터디를 진행하였는데, 동료가 많은 도움을 주어서 나름 쉽게 과제를 수행한 것 같다. 같이 과제를 진행한 동료에게 감사를 표한다.

가장 어려웠던 부분은 유니코드를 처리하는 방법이다. 그리고 의외로 재밌기도 했다. 유니코드를 이런식으로 표현하고 이런 형식으로 이루어졌구나를 알게 되었다. 또한 우리가 과제를 하는 환경이 Mac인데 UTF-8로 되있어서 내가 한 방식대로 bit를 파악하지 않더라도 컴퓨터에서 알아서 유니코드로 인식한다는 것도 알게 되었다.

하지만 이것은 절대 추천하지 않는다. 만약 다른 환경에서 글자가 깨진다면 제대로 된 프로그램이 아니라고 생각한다.

나름 재미있게 했던 과제였던 것 같다. 다른 과제들도 힘들더라도 열심히 진행을 해보고 싶다.

profile
세상을 이롭게 하는 프로그램 만들기

0개의 댓글