🖤UMC 서버 1주차 스터디 - 서버란 무엇인가(소켓 & 멀티 프로세스)🖤
0. 사전 지식
1 ) 시스템 콜
컴퓨터 내에서 수행되는 명령에는 일반 명령과 특권 명령이 있다
일반 명령은 유저가 내릴 수 있는 매우 간단한 명령을 의미하고
특권 명령은 유저가 내릴 수 없는 보안이 필요한 명령을 의미한다
일반 명령은 유저 레벨에서 수행이 가능하지만
특권 명령은 유저 레벨에서 제공하는 함수만으로는 수행이 불가능하기 때문에 커널의 도움을 반드시 받아야 한다
이때 운영체제의 커널이 제공하는 서비스에 접근하기 위한 인터페이스를 시스템 콜이라고 한다
우리는 대부분 특권 명령으로 동작하는 응용 프로그램을 사용하기 때문에
시스템 콜이 빈번하게 일어난다
2 ) 프로세스와 스레드
프로세스 : 운영체제로부터 자원을 할당받은 작업의 단위
스레드 : 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위
프로세스는 운영체제로부터 독립된 메모리 영역을 Code/Data/Stack/Heap의 형식으로 할당받는데
이 때문에 프로세스는 다른 프로세스의 정보에 접근할 수 없다
스레드는 프로세스의 Stack 메모리 영역을 제외한 나머지 영역을 공유한다
이 때문에 스레드는 서로의 Code/Data/Heap 메모리에 접근할 수 있다
프로세스가 서로에게 접근하기 위해서는 IPC를 사용해야 한다
3 ) TCP / IP 계층
한 컴퓨터에서 다른 컴퓨터로 통신하는 것을 네트워크 통신이라고 하는데
네트워크 통신은 기본적으로 일정한 계층을 거쳐가면서 이루어진다
이때 이 계층을 표준화해놓은 것을 OSI 7계층이라 하고
실제로 컴퓨터가 네트워크 통신을 수행할 때는 OSI 7계층을 기반으로 한 TCP/IP 계층 모델에 따라 작동한다
OSI 7계층
계층 7 : 응용 계층
계층 6 : 표현 계층
계층 5 : 세션 계층
계층 4 : 전송 계층
계층 3 : 네트워크 계층
계층 2 : 데이터 링크 계층
계층 1 : 물리 계층
TCP / IP 4계층
계층 4 : 응용 계층 - OSI 7계층의 7, 6, 5계층
계층 3 : 전송 계층 - OSI 7계층의 4계층
계층 2 : 인터넷 계층 - OSI 7계층의 3계층
계층 1 : 네트워크 인터페이스 계층 - OSI 7계층의 2, 1계층
데이터를 송신할 때는 4 ~ 1 계층순으로 작동하고
데이터를 수신할 때는 1 ~ 4 계층순으로 작동한다
4 ) TCP와 UDP의 차이
TCP와 UDP는 전송 계층에서 작동하는 시스템으로 패킷을 한 컴퓨터에서 다른 컴퓨터로 전달하는 역할을 수행한다
TCP는 연결형 시스템으로 클라이언트와 서버간의 신뢰성을 확보하는 일련의 과정을 수행한 뒤 본격적으로 데이터의 송/수신을 진행한다
그렇기 때문에 TCP는 주로 신뢰성이 요구되는 애플리케이션에서 사용된다
UDP는 비연결형 시스템으로 일방적으로 데이터를 넘겨준다
따라서 UDP는 주로 간단한 데이터를 빠른 속도로 전송하고자 하는 애플리케이션에서 사용된다
1. 서버란 무엇인가( 소켓 & 멀티 프로세스 )
서버의 정의
서버 : OS에 의해 동작하는 프로세스이며 클라이언트의 역할을 하는 프로세스와 소켓을 통해 IPC를 수행하는 것
IP 주소와 포트번호
IP 주소 : 컴퓨터를 식별하는 고유 번호
포트번호 : 서버 프로세스를 식별하는 고유 번호
[서버 프로세스가 동작 중인 컴퓨터의 IP 주소]:[서버 프로세스가 부여받은 포트번호]
[203.230.7.2:80]
203.230.7.2의 IP주소를 가진 컴퓨터의 80번 서버 프로세스
컴퓨터가 직접 네트워크에서 통신하는 것이 아니고
컴퓨터에서 동작하는 프로세스가 다른 컴퓨터의 프로세스와 통신하는 것이다
데이터 송신 과정
운영체제의 write 시스템 콜을 통해 데이터를 소켓에 보낸다
-> TCP / UDP 계층, IP 계층, Ethernet을 거쳐 흐름 제어, 라우팅의 작업을 한다
-> NIC를 통해 외부로 데이터를 송신한다
데이터 수신 과정
NIC에서 데이터를 수신한다
-> 인터럽트를 통해 Driver로 데이터를 옮긴다
-> 이후 네트워크 스텍에서 소켓으로 데이터를 옮긴다
-> 수신 대상이 되는 프로세스에 데이터가 도달한다
소켓
소켓은 네트워크 통신에서 데이터를 주고 받을 수 있는 구조체로 데이터 통로의 역할을 수행한다
TCP 전용 소켓(=stream 소켓)
UDP 전용 소켓(=datagram 소켓)
1 ) socket() 시스템콜
socket() : 소켓을 만드는 시스템 콜로 파라미터를 통해 소켓의 기본적은 틀을 생성한다
파라미터
domain : IPv4 or IPv6
type : 소켓의 종류 (stream, datagram)
protocol : 프로토콜의 종류 ( 0 - 시스템이 자체적으로 프로토콜 선택, 6 - TCP, 17 - UDP )
리턴값 : 파일 디스크립터
소켓의 파일 디스크립터가 파라미터를 통해 전송되면
리눅스는 소켓에 데이터를 작성하거나 소켓의 데이터를 읽어들이는 동작을 수행한다
2 ) bind() 시스템콜
bind() : 소켓을 컴퓨터의 IP주소, 서버 프로세스의 포트번호와 묶어주는 시스템 콜
파라미터
sockfd : 바인딩을 할 소켓의 파일 디스크립터
sockaddr : 소켓에 바인딩할 IP 주소, 포트번호를 담은 구조체
socklen_t : 위 구조체의 메모리 크기
3 ) listen() 시스템콜
listen() : 서버 측 소켓을 클라이언트의 요청을 받을 수 있는 상태로 전환하는 시스템 콜
클라이언트의 연결 요청은 서버 내의 백로그 큐에 축적되는데
이때 listen() 시스템콜은 파라미터로 받은 백로그 크기만큼 백로그 큐를 생성하면서 클라이언트의 연결 요청을 받을 준비를 한다
파라미터
sockfd : 소켓의 파일 디스크립터
backlog : 연결 요청을 받아줄 크기 = TCP의 백로그 큐의 크기
- listen()은 연결형인 TCP에서만 수행된다
- 클라이언트가 최초로 서버에 연결 요청을 하여 클라이언트 소켓을 통해 백로그 큐에 들어갈 때 syn 요청을 보낸다
4 ) accept() 시스템콜
accept() : 백로그 큐에 대기 중인 요청을 선입선출로 하나씩 연결에 대한 수립을 해준다
파라미터
sockfd : 백로그 큐의 요청을 받아들이기 위한 소켓의 파일 디스크립터
sockaddr : 선입선출로 빼온 연결 요청에서 알아낸 클라이언트의 주소 정보
socklen_t : 위 구조체의 메모리 크기
- 3-way handshake
TCP는 서버와 클라이언트간의 신뢰성을 확보한 뒤에 본격적인 데이터 송/수신을 진행하는데
이때 신뢰성을 확보하는 과정에서 3-way handshake가 일어난다
listen() 이후 요청을 받을 준비가 완료된 서버에게 클라이언트가 SYN을 통해 요청을 전달하는 것이 그 첫번째 단계이고
이후에 서버에서 accept()를 통해 요청에 대한 응답을 위해 새로운 소켓을 생성한 뒤 서버에서 SYN, ACK을 보내는 것이 두번째 단계이며
마지막으로 클라이언트에서 다시 ACK를 보내는 과정이 일어나면 데이터 송/수신이 가능한 상태(Established)에 도달하게 된다
- 멀티 프로세스
사실 Established 상태에서 바로 데이터의 송/수신이 가능한 것은 아니다
이후에 서버의 성능을 위해 하나의 테크닉이 들어가게 되는데 이를 멀티 프로세스 혹은 멀티 쓰레드라고 부른다
하나의 프로세스인 서버가 수많은 클라이언트의 요청을 받는 상황에서
모든 요청에 대한 응답을 완벽하게 수행한 뒤 다음 요청을 받게 된다면
엄청난 병목이 생길 것이다
그렇게 때문에 서버는 연결 요청을 받는 부분과 응답을 주는 부분을 분리해서 관리한다
이때 연결 요청을 받는 프로세스를 부모 프로세스, 응답을 주는 프로세스를 자식 프로세스라고 하며
부모 프로세스는 socket() 시스템 콜을 통해 생성한 소켓을 이용하고
자식 프로세스는 accept() 시스템 콜을 통해 생성한 소켓을 이용한다
자식 프로세스는 부모 프로세스의 잔업을 마무리한 뒤 종료된다
자식 프로세스를 생성하는 시스템 콜을 fork(), 종료하는 시스템 콜을 exit(0)이라고 한다
5 ) recv(), send()
recv() : 데이터를 수신할 때 사용하는 시스템 콜
send() : 데이터를 송신할 때 사용하는 시스템 콜
서버는 연결을 받는 부분과 응답을 주는 부분을 병렬적으로 배치하여 작동한다