- TCP/IP 프로토콜 구조
[애]플리케이션 계층 - 프로그램 매칭
[전]송 계층(TCP/UDP) - PORT 매칭
[인]터넷 계층(IP) - IP Address 매칭
[네]트워크 계층(EtherNet) - MAC Address 매칭
- 라우팅
목적지까지 데이터를 전달하기 위한 일련의 작업
(라우팅을 위한 정보 획득 및 전달 작업을 포함한다.)
- 라우터
라우팅을 담당하는 전용 컴퓨터
- TCP
연결형 프로토콜
바이트 스트림방식(데이터에 구분이 없음)
신뢰성 있는 데이터 전송
1:1 통신
- UDP
비 연결형 프로토콜
데이터그램 방식(데이터에 대한 구분이 존재)
비신뢰성 통신
1:1/1:n/n:n 통신
- Send 함수
소켓 내 존재하는 송신버퍼에 사용자가 지정한 버퍼의 데이터를 복사해줌
(결국 보내는 건 네트워크단에서 알아서 보내줌)
- Recv 함수
소켓 내 존재하는 수신버퍼에서 사용자가 지정한 버퍼로 데이터를 복사해줌
- 수신버퍼 + 송신버퍼 = 소켓버퍼
- __stdcall
정의 된 함수 내부에서 스택이 정리됨
(cdecl 보다 용량이 작으며, 속도가 빠르지만 가변인자는 불가)
매개변수는 오른쪽에서 왼쪽 순으로 스택 위로 푸시 됨.
- __cdecl
호출한 함수에서 스택을 정리
(가변인자를 지원한다.)
매개변수는 오른쪽에서 왼쪽 순으로 스택 위로 푸시 됨.
- 윈도우는 스레드스케쥴링 기반
- 스레드 기아 현상
우선순위가 높은 스레드가 CPU 할당을 지속적으로 요청 할 경우, 우선
순위가 낮은 스레드의 경우에는 CPU를 할당 받지 못하는 현상(스레드 독차지)
우선순위 0~31까지
- 오버랩 I/O(Overlapped I/O) 특징
비동기식(커널에 요청 후 결과만 받음)
소켓 버퍼 미사용(직접 TCP 버퍼에서 송/수신이 가능)
- IOCP 특징
비동기 입츌력 모델의 완료통지를 받음
제한된 스레드의 수를 통해 n개의 소켓 입출력을 담당
컨텍스트 스위칭에 소모되는 시간을 줄임
Notification 특징을 지님
-> Notification은 WaitFor**** 를 실행 후 WSASend 나 WSARecv 등을 호출함
- 3WayHandshaking(쓰리 웨이 핸드쉐이킹) - TCP에서 Connect 시 일어남
SYN > SYN+ACK > ACK
[CLIENT] [SERVER]
CLOSE LISTEN
SYN-SENT SYN->
SYN-RECEIVED
<- SYN+ACK
ESTABLISHED
ACK->
ESTABLISHED
- 4WayHandshaking(포 웨이 핸드쉐이킹) - TCP에서 Disconnect 시 일어남(우아한 종료)
FIN > ACK+FIN > ACK
[CLIENT] [SERVER]
ESTABLISHED ESTABLISHED
FIN_WAIT1
FIN->
CLOSE_WAIT
<-ACK
FIN_WAIT2 CloseSocket()
<-FIN
TIME_WAIT
ACK->
CLOSED
- 데드레커닝
대상체가 현재 행동을 지속할거란 가정하에 다음 행동을 예측하는 기법
- 오버로딩
매개 변수를 다르게 하여 다중 정의 하는 것
- 오버라이딩
함수를 재정의 하는 것
- 가상함수(가상메소드)
상속하는 클래스 내에서 같은 시그니처의 함수로 오버라이딩 될 수 있는 함수 또는 메소드이다.
- virtual 키워드
서로를 오버라이딩할 수 있고 추후 바인딩이 될 수 있다는 것을 의미
- 소멸자에 virtaul 을 쓰는 이유
[원래 생성자, 소멸자 호출 과정]
생성자 : 부모 클래스 -> 자식 클래스
소멸자 : 자식 클래스 -> 부모 클래스
* 부모 클래스의 포인터로 자식 클래스를 호출 할 때, 가상함수로 정의되지 않은 자식 클래스의 오버라이딩 된 함수를 호출하면 부모 클래스의 멤버 함수가 호출 된다. 소멸자도 자식 클래스에서 오버라이딩 된 함수라고 볼 수 있기 때문에 부모 포인터로 자식 객체를 삭제하면 부모 클래스의 소멸자가 호출된다.
그렇기에 소멸자에도 virtaul 키워드를 이용한다.
- Select 모델
이식성이 좋음(윈도우/리눅스)
64개 이상의 소켓을 처리하려면 여러개의 스레드를 이용
블럭소켓
- AsyncSelect 모델
소켓 이벤트를 윈도우 메세지 형태로 처리함
하나의 프로시저에서 모두 처리해야하기 때문에 성능이 저하 될 수 있음.
논블럭소켓
- EventSelect 모델
Select 와 AsyncSelect 혼합형 / 윈도우를 필요치 않음.
64개 이상 소켓 처리 시 다중 스레드 필요
- 스레드
프로세스에서 실행/제어만 분리한 실행 단위
- 프로세스/스레드
프로세스는 1개 이상의 스레드를 갖는다.
[스레드 실행정보] + [스레드 지역 데이터] + [실행 스택] = 프로세스
- OSI 7계층
[물]리 1
[데]이터 2
[네]트워크 3
[전]송 4
[세]션 5
[표]현 6
[응]용 7
- 스레드 스케쥴링
선점기법(SRT, RR 등)
- 우선순위 시스템에 유리
- 대화식 시스템
비선점기법(FCFS, SJF 등등)
- 한번 제어를 받으면 끝까지 처리
- ARP 프로토콜
주소 결정 프로토콜
IP주소를 기반으로 MAC 주소를 찾음.
- MTU(Maximum Transmission Unit)
한 번 전송에 최대한 담을 수 있는 데이터의 양
최대 전송 유닛(1500 바이트)
1500 이하의 경우 '길이'로 판단
1536 이상인 경우 프로토콜 '종류'로 판단
- IP 프로토콜
송신자 : 주소 해석 후 경로를 결정 하고 다음 호스트로 전송
수신자 : 수신 주소 비교 후 다음 호스트로 전달하거나 TCP 계층으로 전달
- TCP프로토콜
송신자 : 패킷생성(1500 바이트 초과 시 나눠서 생성), 송·수신자 정보를 묶어 IP계층에 전달
수신자 : 패킷을 모아 정보를 만든 후 프로세스/응용 계층에 전달
- 페이지 폴트
프로그램이 물리 메모리에 없는 데이터나 코드에 접근을 시도 할 경우 발생
- 페이지
가상기억장치를 일정한 크기로 나눈 블록
- MMU(Memory Management Unit)
- 템퍼럴 로컬리티
한번 접근이 이뤄진 주소의 메모리 영역에 자주 접근하는 특성
- 스페이셜 로컬리티
이미 접근이 이뤄진 영역의 근처에 접근할 확률이 높은 특성
- 디폴트 힙
디폴트 힙을 구성하는 페이지들은 Reserve(예약)상태이다.
(단, 일부 성능을 위해 Commit(할당) 상태 일 수 있다.)
malloc / free 나 new / delete 를 사용 해 할당 할 경우 디폴트 힙 에서 할당함.
프로세스에 기본적으로 할당되는 메모리 영역
- 다이나믹 힙(동적 힙)
로컬리티가 보장되어 메모리 단편화가 줄어든다.
스레드별 동적힙을 생성한다면, 메모리의 할당과 해제에 동기화가 자유로워진다.
힙 생성 - HeapCreate
힙 할당 - HeapAlloc
힙 반환 - HeapFree
힙 소멸 - HeapDestory
- MMF(Memory Mapped File)
파일의 일부분을 프로세스의 가상메모리 영역과 매핑 시킨다
- 메모리 Commit(할당)
물리메모리에 할당 된 상태
malloc이나 new를 통해 메모리를 할당 받으면 해당 메모리 페이지는 Commit 상태
- 메모리 Reserve(예약)
Commit과 Free의 중간상태로 다른 메모리 함수가 할당 받지 못함
(단, 물리 메모리의 소비는 없음)
- 임계영역(Critical Section)
한 프로세스에서 오직 하나의 스레드 접근만 허용하는 영역
유저 영역
일반적인 동기화 객체보다 빠르고 효율적
- 뮤텍스
오직 하나의 스레드 접근만 허용
(서로 다른 프로세스에 속한 스레드에도 사용 가능)
- 세마포어
한정된 개수의 자원을 여러 스레드가 사용하려고 할 때 접근을 제한함
- 이벤트
특정 사건 발생을 다른 스레드에 알림.
Signaled(신호) / Nonsignaled(비신호) 두 가지의 상태를 갖음
- 대기 가능 타이머(Waitable timer)
특정 시간이 되면 대기 중인 스레드를 깨움
- 소켓옵션
* SOL_SOCKET
이름 |
타입 |
설명 |
SO_BROADCAST |
BOOL |
브로드캐스팅 허용 |
SO_DONTROUTE |
BOOL |
Send 시 라우팅 테이블 참조 생략 |
SO_KEEPALIVE |
BOOL |
주기적 연결 여부 확인 |
SO_LINGER |
linger{} |
보낼 데이터가 있을 경우 closesocket() 함수 리턴 지연 |
SO_SNDBUF SO_RCVBUF |
int |
소켓 송/수신 버퍼 크기 설정 |
SO_SNDTIMEO SO_RCVTIMEO |
int |
send(), recv() 등의 함수에 대한 타임아웃 설정 |
SO_REUSEADDR |
BOOL |
지역주소(IP 주소, 포트번호) 재사용 허용 |
* IPPROTO_IP
이름 |
타입 |
설명 |
IP_HDRINCL |
BOOL |
데이터를 보낼 때 IP 헤더를 포함 |
IP_TTL |
int |
IP 패킷의 TTL(Time to live) 변경 |
IP_MULTICAST_IF |
IN_ADDR{} |
멀티캐스트 패킷을 보낼 인터페이스 설정 |
IP_MULTICAST_TTL |
int |
멀티캐스트 패킷의 TTL 변경 |
IP_MULTICAST_LOOP |
BOOL |
멀티캐스트 패킷의 루프백 여부 설정 |
IP_ADD_MEMBERSHIP IP_DROP_MEMBERSHIP |
ip_mreq{} |
멀티캐스트 그룹 가입과 탈퇴 |
* IPPROTO_TCP
이름 |
타입 |
설명 |
TCP_NODELAY |
BOOL |
Nagle 알고리즘 작동 중지 |
- 블로킹 소켓
호출 시 조건이 만족될 때까지 스래드를 대기 상태로 만듬
- 논블로킹 소켓
호출 시 조건이 만족하지 않아도 리턴하므로 대기 상태가 되지 않음.(WSAWOULDBLOCK <- 오류가 아님)
- APC 큐
비동기 입출력 결과 저장을 위해 OS가 각 스레드마다 할당하는 메모리 영역
- 컨텍스트 스위칭
프로세스의 상태 정보를 저장하고 복원하는 일련의 과정
- 쓰레드의 특성
쓰레드마다 스택을 독립적으로 할당해 준다.
코드 영역을 공유한다.
데이터 영역과 힙을 공유한다.
- 쓰레싱
페이지 폴트율이 높은것
- 스핀락
임계 영역에 진입이 불가능 할 때 진입이 가능 할 때까지 루프를 돌면서 재시도 하는 방식으로 구현된 락
장 : 짧은 시간 안에 진입 할 수 있는 경우 컨텍스트 스위칭을 제거 할 수 있어 효율적(논슬립)
단 : CPU를 비효율적으로 낭비 할 위험이 있음.
- 유저레벨 쓰레드
Fiber(파이버) <- 유니티의 코루틴 같은 녀석
- 커널레벨 쓰레드
_beginthreadex()/CreateThread() 를 통해 생성 한 쓰레드
- 커널 레벨 쓰레드 장단점
장 : 안정성 및 다양한 기능성 제공
단 : 유저모드 <-> 커널모드 잦은 전환으로 인하여 성능저하
- 유저 레벨 쓰레드 장단점
장 : 커널모드로의 전환이 없으므로 성능이 좋음
단 : 커널에 의해 블로킹 되었을 경우 쓰레드가 속해 있는 프로세스 전부가
블로킹 될 수 있음.
- _beginthreadex도 내부적으로 CreateThread 함수를 호출 함. 단 _beginthreadex는쓰레드를 위해 독립적인 메모리 블록을 할당함.
- SRWLock VS CriticalSection
SRWLock는 기존 CriticalSection 보다 조금 더 적은 메모리 사용과 빠른 수행 속도를 가짐
Reader Thread와 Writer Thread가 완전히 분리 될 경우 효율이 좋음
중첩진입이 불가하고, 중첩 진입 시 락이 해제되지 않음
A Thread에서 Lock을 걸고, B Thread에서 UnLock 할 수 있음.
- 유저 모드 동기화
크리티컬 섹션 - 메모리 접근 동기화
인터락 함수 - 메모리 접근 동기화
SRWLock
- 커널 모드 동기화
뮤텍스 - 메모리 접근 동기화
세마포어 - 메모리 접근 동기화
이름 있는 뮤텍스 - 프로세스간 동기화
이벤트 기반의 동기화 - 실행 순서 동기화
- volatile 키워드
최적화를 수행하지 마라!!
메모리에 직접 연산하라(레지스트에 복사해두었던 값이 아닌 메모리의 값을 이용)
- 뮤텍스
접근 허용 쓰레드 수가 하나
Signaled / Non-Signaled 상태
Signaled 상태에는 접근 가능
- 세마포어
접근 허용 스레드 개수를 하나로 제한 한 세마포어는 바이너리 세마포어
바이너리 세마포어는 뮤텍스와 동일한 기능을 제공
- 연산자 우선순위
우선순위 |
연산자 |
0 | 후치 연산자(변수++, 변수--), static_cast<type>() |
1 |
+, -, ~(단항), 전치 연산자(++변수, --변수) |
2 |
! |
3 |
*, /, % |
4 |
+, - |
5 |
<, <=, >, >=(비교) |
6 |
==, !=(비교) |
7 |
&, ^, |(비트 연산자) |
8 |
&&(비교) |
9 |
||(비교) |
10 |
=, +=, -=, *=, /=, |
- L2(데이터 링크 계층)
하나의 지국에서 다른 지국으로 오류 없는 데이터 전달에 대한 책임을 가짐
(개별적인 패킷 각각에 대한 책임)
물리계층을 통해 얻은 이진 신호 점검
오류체크나 복구 기능을 함
네트워크층으로부터 받은 데이터에 주소와 제어정보를 포함하고 시작과 끝에
의미 있는 비트를 추가함.(프레임)
- L2의 기능
node to node 전달(delivery) : station to staion
주소지정(addressing)
접근 제어(access control)
흐름 제어(flow control)
오류 처리(error handling)
동기화(synchronization)
- L3(네트워크 계층)
다중 네트워크 링크를 통해 패킷의 발신지-대-목적지 전달에 대한 책임을 가짐
스위칭(물리적 링크간의 일시적 연결 ex_전화 시스템),
라우팅(한 지점에서 다른 지점으로 패킷 전송 시 다중 경로 중 최적의 경로 선택)을 제공
- L3의 기능
발신지 대 목적지 전달(packet)
논리적 주소 지정(Logical addressing)
라우팅(Routing)
주소 변환(Address transformation)
다중화(Multiplexing)
- L4(전송 계층)
전체 메시지의 발신지 대 목적지(end-to-end) 전달에 대한 책임을 가짐
- L4의 기능
종단-대-종단 전달(End-to-end message delivery)
서비스-점 주소 지정(Service-point(port) addressing)
분할과 재조립(Segmentation and reassembly)
연결 제어(Connection control)
- 서브넷마스크
주어진 IP주소를 네트워크 환경에 맞게 나누어 주기 위해 씌워주는 2진수 조합
커다란 네트워크를 잘게 나누기 위해 필요;.;
- 게이트웨이
일반적으로 하나의 네트워크, 혹은 울타리 안에서 밖으로 빠져나가는 중간 관문
- STL 컨테이너 특징
- LIST
- 이중 링크드 리스트 구조
- 연결 정보를 위해 추가적 메모리 사용
- 이동, 삭제, 삽입이 빠름(최대 장점)
- 선형 탐색
- STL 중 가장 강력한 예외 안정성 제공
- Deque
- 저장 원소가 많고 메모리 할당량이 클 경우 Vector에 비해 확장 비용이 절감
- 메모리공간이 연속적이지 않기에 원소들간 포인터 연산 불가
- Vector
- 연속접근 및 랜덤 엑세스 가능
- 동적으로 확장/축소가 가능한 dynamic array로 구현
- 원소가 할당 가능하고 복사 가능하다면 어떠한 타입도 가능
- 추가,제거는 빠르나 중간 삽입은 느림
- 확장 시 reallocation 비용이 큼, 재할당을 피해야 함
- 원소값을 바로 제거하는 함수가 없음
- Set
- 이진 탐색 트리(레드-블랙 트리), Key만 저장함
- 할당 가능하고, 복사 가능한, 정렬 기준에 따라 비교될 수 있다면, 어떠한 타입도 가능
- 랜덤 액세스 불가
- 모든 원소는 상수로 취급
- 자동 정렬
- 검색 속도 빠름
- Multiset
- Set과 차이는 중복값 허용 여부 차이
- Map
- 이진탐색트리 기반, 균형이진트리(레드-블랙 트리)
- Key/Value를 하나의 쌍으로 취급
- 연관 배열처럼 사용 가능
- 연관 배열과 다르게 어떠한 타입도 가질 수 있음
- 검색속도가 빠름
- Multimap
- Map과 차이는 중복값 허용 여부(단일키:다중 값)
- STL 컨테이너 선택법
- 앞/뒤에 자주 삽입, 삭제 시 메모리 사용량이 줄어들어야 한다면 Deque
- 원소의 삽입,삭제,이동이 중간 위치에서 자주 발생한다면 List
- 원소의 검색이 자주 발생한다면 Set, MultiSet을 고려
- 연관 배열은 Map
- 사전이 필요하다면 MultiMap
- TCP 혼잡제어
- 징후
- 라우터에서 버퍼가 오버플로우 되어 패킷 손실이 발생
- 라우터 버퍼에서 긴 큐잉 지연(Queueing delay) 발생
- 알고리즘
- AIMD
- Slow Start
- 타임아웃에 대한 반응
- MSS(Maxim Segment Size)
- TCP 상에서 전송 할 수 있는 사용자 데이터의 최대 크기
- MSS = MTU(1500Byte) - IP헤더크기(최소20Byte) - TCP헤더크기(최소 20Byte)
- 통상적인 1460Byte의 크기
- Nonpaged Pool(비페이징풀)
- Paged Pool(페이징 풀)
애초부터 물리 메모리에 상주하며 페이징 되지 않도록 만들어 놓은 영역
페이지 폴트가 없다보니 접근 속도 또한 빠르며, 고레벨 IRQL(Interupt Request Level)접근이 오류 없이 가능
page-locking(4000Byte)
커널이 메모리에 접근하기 위해 해당 메모리 페이지를 잠금
Send / Recv
1Byte만 보내거나 받아도 4000Byte가 Lock이 걸림
- TIME_WAIT 이 필요한 이유
지연 패킷이 발생 할 경우
이미 다른 연결로 진행 되었다면, 지연 패킷이 뒤늦게 도달해 문제가 발생
매우 드문 경우이긴 하나, 때마침 SEQ까지 동일하다면 잘못된 데이터를 처리하게됨.(무결성에 문제가 생김)
원격 종단의 연결이 닫혔는지 확인해야 할 경우
마지막 ACK 유실 시 상대방은 LAST_ACK 상태에 빠지고, 새로운 SYN 패킷 전달 시 RST를 리턴함.
새로운 연결은 오류를 내며 실패.(이미 연결을 시도한 상태이기 때문에 상대방에게 접속 오류 메세지)