Skip to content

Commit

Permalink
fix: Merge branch 'woowa/main' of https://github.com/SSUMC-6th/Spring…
Browse files Browse the repository at this point in the history
…_Boot_A into woowa/#21
  • Loading branch information
SoulTree-Lovers committed May 6, 2024
2 parents 4e9e696 + 21af0ea commit 33fb19f
Show file tree
Hide file tree
Showing 14 changed files with 519 additions and 0 deletions.
Binary file added docs/.DS_Store
Binary file not shown.
Binary file added docs/chapter1/.DS_Store
Binary file not shown.
177 changes: 177 additions & 0 deletions docs/chapter1/Ch01Keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# Chapter 1. 서버란 무엇인가 (소켓&멀티 프로세스)

> UMC 워크북 1주차 키워드에 관한 내용을 정리해보겠습니다 :)


## ✅ TCP

TCP는 신뢰성 있는 통신을 보장하기 위해 사용되는 프로토콜이다.

![3way-handshake](https://velog.velcdn.com/images%2Fnnnyeong%2Fpost%2F9943de2b-96d8-4e63-b9cc-46c1a89e20a3%2Fimage.png)

![4-way Handshake](https://images.velog.io/images/nnnyeong/post/fd5029e1-b84c-4fa3-9f7b-d5f702f1b1b9/image.png)

- 클라이언트와 서버 간 **1대1 통신**이며, **연결 시 3-way handshaking**을 통해 연결하고 **종료 시 4-way handshaking**을 통해 연결을 종료한다. 연결 종료 시 일방적인 종료를 하지 않는 것을 보고 '우아한 종료'라고 불리기도 한다.

- 패킷이 손실되는 것을 방지하며 **중복된 패킷이 없도록, 패킷의 순서가 바뀌지 않도록 보장**해준다.

- 전이중 방식이므로 종단 간 양 프로세스가 **서로 동시에 세그먼트를 전송**할 수 있다. 양 방향 각각에 대해 ‘송수신 버퍼’ 및 데이터 흐름용 순서 번호’를 유지하고 있다.

- **Flow Control**을 통해 송/수신 속도를 적절히 조절하며, **Congestion Control**을 통해 호스트가 속한 네트워크가 혼잡한 경우 송신률을 감속하여 네트워크 전체의 혼잡도를 낮춘다.



## ✅ UDP

TCP와는 다르게 **연결을 하지 않고 패킷을 전송**하는 방식이다. 신뢰성을 보장하지 않지만, 그로 인해 비교적 데이터 전송 속도가 빠르다. 따라서, 일부 데이터가 손실되어도 크게 지장이 없는 실시간 영상 스트리밍 등에 사용이 가능하다.



![TCP와 UDP 차이](/Users/kangseungmin/Library/Application Support/typora-user-images/image-20240407130511801.png)

> TCP와 UDP의 차이점은 위 표를 통해 확인할 수 있다.


## ✅ System Call

사용자 모드에서 시스템 내부의 함수들을 직접 호출했을 경우, 악용한다면 시스템 전체에 문제가 발생할 수 있다. 이를 방지하기 위해 사용자가 직접 시스템에 접근하지 않고 운영체제를 통해 간접적으로 접근하기 위해 시스템 콜을 사용한다.

![OS 서비스와 시스템콜 | CloudStudying](https://i.imgur.com/UH0DDZt.png)

> 위 그림 처럼 응용 프로그램이 printf() 함수를 호출하면, standard C Library에 정의된 write()라는 시스템 콜을 호출함으로써 OS가 터미널에 "Hello World!"를 출력하는 것이다.


## ✅ Hardware Interrupt

![OS Interupt](https://miro.medium.com/v2/resize:fit:721/1*U8pHdVCB8vh-YDWpk_Kc9w.png)

인터럽트의 일종으로 키보드, 디스크 드라이브, 입출력[ ](https://terms.tta.or.kr/dictionary/dictionaryView.do?subject=입출력+접속구)접속구 등 하드웨어 장치에 의해서 외부적으로 생성되거나 마이크로프로세서에 의해서 내부적으로 생성되는 인터럽트(서비스 요구). 외부 하드웨어 인터럽트는 장치들이 컴퓨터의 마이크로프로세서로부터의 지시를 요구하는 데 사용된다. 내부 하드웨어 인터럽트는 IBM PC 및 그 호환기 속에 들어 있는 마이크로프로세서에 의해서 어떤 이벤트를 제어하기 위해 생성된다.

예를 들면, **프로그램이 불법 동작인 제로에 의한 나눗셈을 하려는 것과 같이 이벤트를 보고하기 위해 사용**된다. 하드웨어 인터럽트는 키보드에서 입력된 문자를 받았을 때와 같이 **무작위적으로 발생**할 수도 있고, **컴퓨터의 타이머(timer)에 의해서 예측적으로 발생**할 수도 있다. 마이크로프로세서는 긴급한 요구와 긴급하지 않은 요구를 판별할 수단이 필요하므로 하드웨어 인터럽트에는 우선 순위의 레벨이 할당되어 있다. 최우선 순위의 인터럽트는 마스크 불가능 인터럽트(NMI)라고 불리는데, 기억 장치의 고장 등 즉시 서비스가 필요한 심각한 오류에 대처하는 인터럽트이다.



## ✅ 리눅스의 파일과 파일 디스크립터

![리눅스 시스템 프로그래밍 챕터 2 · Showerbugs](https://web.cs.ucla.edu/classes/fall08/cs111/scribe/4/FDT_diagram.JPG)

**변수는 메모리에 존재하지만, 파일은 디스크에 존재**한다. 어떤 데이터를 일시적으로 저장하는 것이 아닌 영구 저장할 경우 파일을 사용할 수 있다. 파일 디스크립터를 통해 파일을 구별할 수 있다. 꼭 파일이 아니더라도 **키보드, 모니터** 등의 디바이스 또한 파일 디스크립터를 통해 접근한다.

프로세스 간 통신을 위해 사용하는 **소켓**도 파일의 구현체 중 하나이다. 소켓도 파일 디스크립터를 통해 접근할 수 있다!



## ✅ socket()

```c
int socket(int domain, int type, int protocol);
```
소켓을 생성하는 시스템 콜이다. domain, type, protocol을 설정할 수 있다. 함수가 실행되면 해당 소켓을 가리키는 **소켓 디스크립터를 반환**한다. -1이 반환되면 소켓 생성 실패, 0 이상의 값이 나오면 소켓 디스크립터를 반환한 것이다.
- `domain`: 어떤 영역에서 통신할 것인지에 대한 영역을 지정한다.
- AF_UNIX (프로토콜 내부에서)
- AF_INET (IPv4를 사용)
- AF_INET6 (IPv6를 사용)
- `type`: 소켓의 데이터 전송 방식을 설정한다.
- SOCK_STREAM (연결지향형 소켓; 스트림을 의미하며 TCP일 때 사용한다.)
- SOCK_DGRAM (비연결지향형 소켓; 데이터 그램을 의미하며 UDP일 때 사용한다.)
- SOCK_RAW (사용자 정의; 프로토콜의 헤더를 직접 다룰 때 사용한다.)
> 송수신하는 패킷들의 데이터를 볼 수 있기 때문에 보안 상의 이유로 root 권한으로 실행시켜야 한다!!
- `protocol`: 통신에 사용할 프로토콜을 설정한다.
> 보통 0을 넣는다. (0을 넣으면 domain과 type을 보고 자동으로 지정해준다.)
- IPPROTO_TCP (TCP 프로토콜 사용)
- IPPROTO_UDP (UDP 프로토콜 사용)
- IPPROTO_HOPOPTS (0과 같은 역할이다.)
## ✅ bind()
```c
int bind(int sockfd, struct sockaddr *myaddr, int addrlen);
```

위에서 생성된 **소켓의 IP 주소와 Port 번호를 할당**하는 시스템 콜이다. 클라이언트 측 IP와 Port 번호는 자동으로 할당되기 때문에 서버 측에서만 사용한다.

> - IP는 컴퓨터를 구분하는 용도로 사용되며, PORT 번호는 소켓을 구분하는 용도로 사용된다.
>
> - 하나의 하나의 프로그램 내에서는 둘 이상의 소켓이 존재할 수 있으므로, 둘 이상의 PORT가 하나의 프로그램에 의해 할당될 수 있다.
> - PORT 번호는 16비트로 표현하며, 그 값의 범위는 0 ~ 65535 이다.
> - 0 ~ 1023 번호는 잘 알려진 PORT(Well-Known PORT)라 해서 이미 용도가 결정되어 있다.


- `sockfd`: 주소 정보를 할당할 소켓의 파일 디스크립터를 지정한다.
- `myaddr`: 할당하고자 하는 주소정보를 지니는 구조체 변수의 주소 값을 넣는다.
- `addrlen`: 두 번째 인자로 전달된 구조체 변수의 길이 정보를 담고 있다.



## ✅ listen()

```c
int listen(int sock, int backlog);
```
![](/Users/kangseungmin/Downloads/IMG_FCD00A1F7C1A-1.jpeg)
대기 큐를 만드는 시스템 콜이다. UDP에서는 사용하지 않고 TCP에서만 사용하며, 소켓을 통해 **연결 요청을 기다리며** 연결요청을 받을 **클라이언트 대기 큐의 크기를 설정**할 수 있다.
- `sock`: 연결요청 대기 상태에 두고자 하는 소켓의 파일 디스크립터를 전달한다. 이 함수의 인자로 전달된 디스크립터의 소켓이 서버 소켓(리스닝 소켓)이 된다.
- `backlog`: 연결요청 대기 큐의 크기 정보를 전달한다.
- ex) 5가 전달되면 큐의 크기가 5가 되어 클라이언트의 연결 요청을 최대 5개까지 대기시킬 수 있다.
## ✅ accept()
```c
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);
```

![](/Users/kangseungmin/Downloads/IMG_AE9B0844F5FC-1.jpeg)

서버 측에서 대기 큐에 있는 **클라이언트의 요청을 수락**하기 위한 시스템 콜이다. **새로운 소켓을 만들어 클라이언트와 연결하고, 기존 소켓은 또 다른 클라이언트의 요청을 수락하기 위해 남게 된다.**



- `sock`: 서버 소켓의 파일 디스크립터를 전달한다.
- `addr`: 연결요청을 한 클라이언트의 주소 정보를 담을 변수의 주소 값을 전달한다. 함수 호출이 완료되면 인자로 전달된 주소의 변수에는 클라이언트의 주소 정보가 채워진다.
- `addrlen`: 두 번째 매개변수 addr에 전달된 주소의 변수 크기를 바이트 단위로 전달한다. 단, 크기 정보를 변수에 저장한 다음 변수의 주소 값을 전달한다. 함수 호출이 완료되면 크기 정보로 채워져 있던 변수에는 클라이언트의 주소 정보 길이가 바이트 단위로 계산되어 채워진다.





## ✅ 멀티 프로세스

![기술 면접 대비 CS 전공 핵심요약집: 1.2.5 멀티 프로세스와 멀티 스레드 - 1](https://thebook.io/img/080367/030.jpg)

하나의 프로세스가 여러 클라이언트의 요청을 받아들일 때 태스크를 하나씩 수행하려면 병목현상이 발생한다. 이를 방지하기 위해, 하나의 클라이언트에 하나의 프로세스를 할당해서 태스크를 처리한다. 이를 위한 기법이 멀티 프로세스이다.

**멀티 프로세스 기법은 메모리를 공유하기 어렵다는 단점**이 있다. 이를 극복하기 위해 하나의 프로세스에서 여러 작업을 수행하는 멀티 쓰레드 기법이 등장했다. 하나의 프로세스가 생성한 **여러 쓰레드는 각자 고유한 스택 영역을 가지며, 그 외의 힙, 데이터, 코드 영역은 서로 간 공유**할 수 있다. 이로 인해 문맥 교환(Context Switching) 비용이 감소한다.



## ✅ 병렬 처리

![병렬처리(1)](https://velog.velcdn.com/images/ing06047/post/8822e542-5d70-460a-9a92-24988e7b233f/image.png)

병렬 처리는 여러 테스크를 동시에 처리하는 것을 의미한다. **하지만 실제로는 동시에 처리되는 것이 아닌, 스케쥴링을 통해 CPU의 자원을 적절히 할당받아 태스크를 수행**한다. 스케쥴링 기법으로는 FIFO, SJF, RR 등이 존재한다.
Binary file added docs/chapter2/CIDR_class.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/chapter2/CIDR_format.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 33fb19f

Please sign in to comment.