diff --git a/Linux/Signal2.md b/Linux/Signal2.md new file mode 100644 index 0000000..a1eeb6d --- /dev/null +++ b/Linux/Signal2.md @@ -0,0 +1,219 @@ +## Signal (2) + +⭐️ 표시가 들어있다면 중요한 개념, 없으면 그냥 이런게 있구나~ 느끼고 가시면 됩니다. + +### ✅ Intro + +- 저번 시간에는 signal이 무엇인지 알아봤다. +- 마지막에 signal이 무시될 수도 있다고 말했고, signal 집합이 있다고 말했다. +- 이번 시간은 signal 집합인 sigset_t를 알아볼 것이고, 이게 어떤 set들로 구성되어있는지 살펴볼것이다. +- 특히 sigprocmask에서 정신을 잃을수 있으니 조심할것. + +### ⭐️sigset_t + +- 신호를 관리하기 위한 집합 +- 사용 예시 + +```cpp +sigset_t set; +sigset(&set); +``` + +- sigset_t는 두가지로 이루어짐 + - pending된 set + - block된 set + - 디폴트 값은 Pending set + +### ✅ block set + +- block : 시그널을 보내도 안받겠다 +- 차단된 신호는 즉시 처리되지 않고 대기 상태로 유지 +- 후술할 sigprocmask 함수들을 사용해 block set을 설정하거나 수정 가능 +- 특정 신호를 일시적으로 무시하거나 처리하지 않도록 설정시 사용 + 🧩 block된 시그널들은 블록해제 될 동안 busy-waiting할까? + - block된 시그널은 sigprocmask를 통해 블록이 해제되기 까지 기다려야 + - busy-waiting처럼 CPU를 의미없이 소비하면서 시그널을 확인하는게 아닌 기다리는 동안 다른 일을 하거나 대기가능! + +```cpp +#include +#include + +int main() { + sigset_t blockSet; + sigemptyset(&blockSet); + sigaddset(&blockSet, SIGINT); // SIGINT 신호를 블록 세트에 추가 + + if (sigprocmask(SIG_BLOCK, &blockSet, NULL) == -1) { + perror("sigprocmask"); + return 1; + } + + printf("SIGINT 신호가 블록되었습니다.\n"); + // 여기서 SIGINT 신호는 처리되지 않고 대기 상태로 유지 + + return 0; +} + +``` + +### ✅ pending set + +- pending : 바빠서 처리를 못함, 차단된 상태에서 도착하여 대기중 +- **block set 에 의해 처리되지 못한 신호들이 여기에 저장** +- 블록된 신호들이 언제 도착했는지 추적 가능 +- 블록이 해제될 때 pending set에 있는 신호들 처리 가능 + +```cpp +#include +#include + +int main() { + sigset_t pendingSet; + + // 현재 펜딩 세트를 가져옴 + if (sigpending(&pendingSet) == -1) { + perror("sigpending"); + return 1; + } + + // SIGINT 신호가 펜딩 세트에 있는지 확인 + if (sigismember(&pendingSet, SIGINT)) { + printf("SIGINT 신호가 펜딩 세트에 있습니다.\n"); + } else { + printf("SIGINT 신호가 펜딩 세트에 없습니다.\n"); + } + + return 0; +} + +``` + +### ⭐️ sigprocmask + +```cpp +int sigprocmask(int how,sigset_t *newset,sigset_t *oldset); +``` + +- 현재의 시그널 마스크를 검사하거나 변경하는 시스템콜 함수 +- 시그널 발생 시 나중에 시그널 처리하기 위해 시그널을 블록시킨다. +- 특정 작업 실행하기 위해 시그널을 블록시키고, 특정 작업 실행 마치고 난 후 블록해제하는데 사용 + +🧩 시그널마스크는 뭘까? + +- mask == block +- 시그널 마스크 => 처리할 시그널을 거르는 필터 +- sigrpocmask => 필터의 상태를 변경해 시그널을 프로세스가 처리 가능하게 하거나 블락하게 함 + +**how에 들어가는 인자** + +| 이름 | 역할 | +| ----------- | ------------------------------------------------------------------------------------------------------------- | +| SIG_BLOCK | 현재 시그널 마스크와 시그널 집합의 합집합이 프로세스의 새 프로세스 마스크 | +| SIG_UNBLOCK | 블록된 시그널에 대해 블록 해제시 사용 | +| SIG_SETMASK | 이전 블록된 시그널 집합을 모두 지우고, set이 가리키는 시그널 집합 값이 프로세스의 새로운 시그널 마스크로 설정 | + +### sigemptyset + +```cpp +int sigemptyset(sigset_t *set); +``` + +- set인자가 가리키는 시그널 집합을 빈집합으로 + +### sigaddset + +```cpp +int sigaddset(sigset_t *set, int signo); +``` + +- 인자로 받는 signo에 대한 시그널을 시그널 집합에 추가 + +### sigdelset + +```cpp +int sigdelset(sigset_t *set,int signo); +``` + +- 인자로 받는 signo에 대한 시그널을 시그널 집합에서 제거 + +### 예제 + +```cpp +#include + +sigset_t set; +sigemptyset(&set); // 초기화 +sigaddset(&set, SIGINT); // SIGINT 신호 추가 + +// SIGINT 신호를 차단 +if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { + perror("sigprocmask"); +} + +``` + +### 예제2 + +```cpp +#include +#include +#include + +// 시그널이 처리되었는지 확인하기 위한 전역 변수 +volatile sig_atomic_t gotSIGINT = 0; + +// SIGINT(CTRL + C) 시그널 핸들러 +void handler(int signo) { +if (signo == SIGINT) { +gotSIGINT = 1; +write(STDOUT_FILENO, "\nSIGINT Received\n", 17); // 비동기 시그널 핸들러 내 출력 +} +} + +int main() { +// 1. SIGINT에 대한 시그널 핸들러 등록 +struct sigaction act; +act.sa_handler = handler; +sigemptyset(&act.sa_mask); +act.sa_flags = 0; +sigaction(SIGINT, &act, NULL); + + // 2. sigsuspend()가 대기할 시그널 집합 구성 + // 모든 시그널을 막은 뒤(SIG_FILLSET), SIGINT만 허용하도록 제외 + sigset_t set; + sigfillset(&set); + sigdelset(&set, SIGINT); + + // 3. SIGINT을 기다리는 루프 + while (!gotSIGINT) { + printf("SIGINT 대기 중...\n"); + // sigsuspend()는 지정한 시그널 집합에 들어오지 않는 시그널이 발생할 때까지 실행을 멈춤. + // 여기서는 SIGINT가 들어오면 핸들러 호출 후 반환. + sigsuspend(&set); + } + + printf("SIGINT 처리 완료. 프로그램 종료.\n"); + return 0; + +} +``` + +1.시그널 핸들러를 먼저 만든다. 2. fillset으로 모든 시그널 블록킹 3. delset으로 블록킹 안할 시그널 추려내기 4. SIGINT 시그널 발생 전까지 while 무한루프에 갇혀있음(블록킹 당하기때문!) 5. SIGINT 발생 후 -> while문 탈출! + +### ⭐️ sigpending + +```cpp +#include +int sigpending(sigset *set); +``` + +- block 중이거나 pending 중일때 시그널이 오고 싶은걸 알고 싶을때 사용 +- 특히 block 중일때 시그널이 온것을 알고 싶을 때 사용 +- pending set은 sigpending과 관련있고, block set은 sigsuspend와 관려있다. +- set인자가 가리키는 곳에 호출한 프로세스의 시그널이 블록되어 있으며 현재 pending중인 시그널 집합들이 저장됨. +- sigpending 예제는 sigaction과 같이 봐야 이해가 되기에 다음주에 함께 첨부할 예정 + +### ✅ Outro + +- 이번 장부터 시그널이 매우 어려워지기 시작했다. +- 다만 시그널의 매력은 디몬에서 나오는 것 같다! 좀만 더 기다려달라구! diff --git a/Linux/http_request_message.md b/Linux/http_request_message.md deleted file mode 100644 index 8947522..0000000 --- a/Linux/http_request_message.md +++ /dev/null @@ -1,75 +0,0 @@ -# 1. HTTP Request Mesasge 작성 - -## 1.1. 브라우저에 URL 입력 - -### 각종 URL 형식 -- `http://user:password@www.cyber.co.kr:80/dir/file1.html` - - HTTP 프로토콜로 웹 서버에 액세스하는 경우 - - `http:`: 프로토콜 (데이터 출처에 액세스하는 방법, 통신 동작의 규칙) - - `//`: 나중에 이어지는 문자열이 서버의 이름임을 나타냄 - - `user`: 사용자명(생략 가능) - - `password`: 패스워드(생략 가능) - - `www.cyber.co.kr`: 웹 서버의 도메인명 - - `80`: 포트 번호(생략 가능) - - `/dir/file1.html`: 파일의 경로명 -- `ftp://user:password@ftp.cyber.co.kr:21/dir/file1.html` - - FTP 프로토콜로 파일을 다운로드하거나 업로드하는 경우 - - `ftp:`: 프로토콜 (데이터 출처에 액세스하는 방법, 통신 동작의 규칙) - - `//`: 나중에 이어지는 문자열이 서버의 이름임을 나타냄 - - `user`: 사용자명(생략 가능) - - `password`: 패스워드(생략 가능) - - `ftp.cyber.co.kr`: FTP 서버의 도메인명 - - `21`: 포트 번호(생략 가능) - - `/dir/file1.html`: 파일의 경로명 -- `file://localhost/c:/path/file1.zip` - - 클라이언트 PC 자체의 파일에서 데이터를 읽어오는 경우 - - `file:`: 프로토콜 (데이터 출처에 액세스하는 방법, 통신 동작의 규칙) - - `//`: 나중에 이어지는 문자열이 서버의 이름임을 나타냄 - - `localhost`: 컴퓨터명(생략 가능) - - `c:/path/file1.zip`: 파일의 경로명 -- `mailto:tone@cyber.co.kr` - - 메일을 송신하는 경우 - - `mailto:`: 프로토콜 (데이터 출처에 액세스하는 방법, 통신 동작의 규칙) - - `tone@cyber.co.kr`: 메일 주소 -- `news:comp.protocols.tcp-ip` - - 뉴스그룹의 기사를 읽는 경우 - - `news:`: 프로토콜 (데이터 출처에 액세스하는 방법, 통신 동작의 규칙) - - `comp.protocols.tcp-ip`: 뉴스그룹명 - -## 1.2. 브라우저가 URL 해독 - -웹 서버에 액세스하는 경우를 예로 설명한다. - -- `http://www.lab.cyber.co.kr/dir1/file1.html` - - 프로토콜: `http` - - 웹서버명: `www.lab.cyber.co.kr` - - 데이터 출처(파일)의 경로명: `dir1/file1.html` - - 결론: `www.lab.cyber.co.kr`이라는 웹 서버에 있는 `/dir1/file1.html`이라는 경로의 파일, 즉 `/dir1/`이라는 디렉토리의 아래에 있는 `file1.html` 파일에 액세스한다는 의미 - -## 1.3. 파일명을 생략한 경우 - -- `http://www.lab.cyber.co.kr/dir/` - - `/dir/`의 다음에 써야 할 파일명을 쓰지 않고 생략한 경우 어느 파일에 액세스해야 할지 모름 - - 따라서 파일명을 생략할 때를 대비하여 파일명을 미리 서버측에 설정해 둠 - - 이 설정은 서버에 따라 다르지만 보통 `index.html` 또는 `default.html`이라는 파일명을 설정해 둠 - - 따라서 파일명을 생략한 경우 `dir/index.html` 또는 `dir/default.html`이라는 파일에 액세스 - -- `http://www.lab.cyber.co.kr/` - - 이와 같이 웹 서버의 도메인명만 쓴 URL의 경우도 파일명을 생략한 경우임 - - 끝에 `/`가 있으므로 `/`라는 디렉토리(루트 디렉토리)가 지정되고 파일명은 생략된 것 - - 따라서 `/index.html` 또는 `/default.html`이라는 파일에 액세스 - -- `http://www.lab.cyber.co.kr` - - 이렇게 끝의 `/`까지 생략된 경우도 인정해줌 - - 이 경우에도 `/index.html` 또는 `/default.html`이라는 파일에 액세스 - -- `http://www.lab.cyber.co.kr/whatisthis` - - 이 경우 `whatisthis`를 파일명으로 보는 것이 맞을까? 아니면 디렉토리명이고 파일명은 생략된 형태로 보는 것이 맞을까? - - 이 경우 웹 서버에 `whatisthis`라는 파일이 있으면 파일명으로 보고, `whatisthis`라는 디렉토리가 있으면 디렉토리명으로 보는 것이 통례 - - 같은 이름을 가진 파일과 디렉토리를 둘 다 만들 수 없으므로 `whatisthis`라는 파일과 `whatisthis`라는 디렉토리가 둘 다 존재하는 경우는 없음 - -## 1.4. HTTP의 기본 개념 - -## 1.5. HTTP 리퀘스트 메시지 작성 - -## 1.6. 응답 수신