TCP/IP
18 posts
Server
TCP/IP
C
C++
February 12, 2024
Overlapped IO와 IOCP

Overlapped IO와 IOCP Non-Blocking 모드의 소켓 구성하기 앞서 epoll관련 포스팅에서 논블로킹 모드로 동작하는 소켓의 생성한 적이 있다. 이와 유사하게 윈도우에서는 다음의 함수호출을 통해서 논블로킹 모드로 소켓의 속성을 변경한다. 위의 코드에서 호출하는 ioctlsocket 함수는 소켓의 IO방식을 컨트롤하는 함수이다. 그리고 위와 같은 형태로의 함수호출이 의미하는 바는 다음과 같다. “핸들 hLisnSock이 참조하는 소켓의 입출력 모드(FIONBIO)를 변수 mode에 저장된 값의 형태로 변경한다.” 즉, FIONBIO는 소켓의 입출력 모드를 변경하는 옵션이며, 이 함수의 세 번쨰 인자로 전달된 주소 값의 변수에 0이 저장되어 있으면 블로킹 모드로, 0이 아닌 값이 저장되어 있으면 논블로킹 모드로 소켓의 입출력 속성을 변경한다. 그리고 이렇게 속성이 논블로킹 모드로 변경되면, 논블로킹 모드로 입출력 되는 것 이외에 다음의 특징도 지니게 된다. 클라이언트…

Server
TCP/IP
C
C++
February 04, 2024
Overlapped IO 모델

Overlapped IO 모델 이전 Asychronous Notification I/O 모델에서 비동기로 처리되었던 것은 ‘IO’가 아닌 ‘Notification(알림)‘이었다. 그러나 여기서는 IO를 비동기로 처리하는 방법에 대해 설명한다. 이 둘의 차이점을 명확히 알고 장단점 구분할 수 있어야 이후의 IOCP를 쉽게 공부할 수 있다. IO 중첩 💡 헷갈려서 정리하는 비동기와 논블로킹 차이 동기 / 비동기 : IO 작업 A,B,C를 요청했을때, 응답 순서가 A,B,C가 보장되면 동기, 보장되지 않으면 비동기 블로킹 / 논블로킹 : 함수가 작업 완료 전까지 반환되지 않으면 블로킹, 작업 완료 전에 호출과 거의 동시에 반환하면 논블로킹 Overlapped IO socket의 생성 : 프로토콜 체계 정보 전달 : 소켓의 데이터 전송방식에 대한 전달 : 두 소켓 사이에 사용되는 프로토콜 정보 전달 : 생성되는 소켓의 특정 정보를 담고 있는 WSAPROTOCOL_INFO 구조체 변수의 주…

Server
TCP/IP
C
C++
February 03, 2024
Asynchronous Notification IO 모델

Asynchronous Notification IO 모델 WSAEventSelect 함수와 Notification : 관찰대상인 소켓의 핸들 전달 : 이벤트 발생유무의 확인을 위한 Event 오브젝트의 핸들 전달. : 감시하고자 하는 이벤트의 유형 정보전달. 즉, WSAEventSelect 함수는 매개변수 s에 전달된 핸들의 소켓에서 lNetworkEvents에 전달된 이벤트 중 하나가 발생하면, hEventObject에 전달된 핸들의 커널 오브젝트를 상태로 바꾸는 함수이다. 때문에 이 함수를 가리켜 “Event 오브젝트와 소켓을 연결하는 함수”라고 하기도 한다. 세번째 인자인 에 전달할 수 있는 이벤트의 종류는 다음과 같다. : 수신할 데이터가 존재하는가? : 블로킹 없이 데이터 전송이 가능한가? : Out-of-Band 데이터가 수신되었는가? : 연결 요청이 있었는가? : 연결의 종료가 요청되었는가? select 함수는 여러 소켓을 대상으로 호출이 가능한데, WSAEventS…

Server
TCP/IP
C
C++
February 03, 2024
동기화 기법의 분류와 CRITICAL_SECTION 동기화

동기화 기법의 분류와 CRITICAL_SECTION 동기화 유저모드와 커널모드 유저모드: 응용 프로그램이 실행되는 기본 모드로, 물리적인 영역으로의 접근이 허용되지 않으며, 접근할 수 있는 메모리의 영역에도 제한이 따른다. 커널모드: 운영체제가 실행될 때의 모드로, 메모리 뿐만 아니라, 하드웨어의 접근에도 제한이 따르지 않는다. 유저모드 동기화 운영체제의 도움 없이 응용 프로그램 상에서 진행되는 동기화가 바로 유저모드 동기화이다. 유저모드 동기화의 가장 큰 장점은 다음과 같다. “속도가 빠르다.” CRITICAL_SECTION 기반의 동기화 또한 유저모드 동기화의 일종이다. 커널모드 동기화 유저모드 동기화에 비해 제공되는 기능이 더 많다. Dead-Lock에 걸리지 않도록 타임아웃의 지정이 가능하다. Mutex, Semaphore, Event 기반의 동기화가 커널모드 동기화의 일종이다. CRITICAL_SECTION 기반의 동기화 CRITICAL_SECTION 기반의 동기화에서는 …

Server
TCP/IP
C
C++
February 03, 2024
Windows 쓰레드

Windows 쓰레드 윈도우에서의 쓰레드 생성방법 운영체제는 쓰레드의 관리를 위해서 커널 오브젝트도 함께 생성한다. 이 커널 오브젝트의 구분자 역할을 하는, 정수로 표현되는 ‘핸들(Handle)‘을 반환한다. 참고로 핸들은 리눅스의 파일 디스크립터에 비유된다. : 쓰레드의 보안관련 정보전달, 디폴트 보안설정을 위해서 NULL 전달. : 쓰레드에게 할당할 스택의 크기를 전달, 0 전달시 디폴트 크기의 스택 생성. : 쓰레드의 main 함수정보 전달. : 쓰레드의 main 함수호출 시 전달할 인자정보 전달. : 쓰레드 생성 이후의 행동을 결정, 0을 전달하면 생성과 동시에 실행 가능한 상태가 된다. : 쓰레드 ID의 저장을 위한 변수의 주소 값 전달. 복잡해 보이지만, 실제로 신경 쓸 것은 와 두 가지 정도이며, 나머지는 0 또는 NULL을 전달하면 된다. 윈도우 쓰레드의 소멸시점 윈도우 쓰레드의 소멸시점은 쓰레드에 의해서 처음 호출된 쓰레드의 main 함수가 반환하는 시점이다(이렇…

Server
TCP/IP
C
C++
January 31, 2024
Epoll의 이해와 활용

Epoll의 이해와 활용 select 기반의 IO 멀티플렉싱이 느린 이유 함수호출 이후에 항상 등장하는 모든 파일 디스크립터를 대상으로 하는 반복문 함수를 호출할 때마다 인자로 매번 전달해야 하는 관찰대상에 대한 정보들 epoll의 경우는 다음의 장점이 있다. 상태변화의 확인을 위한,전체 파일 디스크립터를 대상으로 하는 반복문이 필요 없다. 함수에 대응하는 함수호출 시, 관찰대상의 정보를 매번 전달할 필요가 없다. Epoll의 함수 : epoll 파일 디스크립터 저장소 생성 : 저장소에 파일 디스크립터 등록 및 삭제 : select 함수와 마찬가지로 파일 디스크립터의 변화를 대기한다. select 방식에서는 관찰대상인 파일 디스크립터의 저장을 위해서 fd_set형 변수를 직접 선언했었다. 하지만 epoll 방식에서는 관찰대상인 파일 디스크립터의 저장을 운영체제가 담당한다. 이때 사용되는 함수가 로, 파일 디스크립터의 저장을 위한 저장소의 생성을 운영체제에게 요청한다. 관찰대상…

Server
TCP/IP
C
C++
January 19, 2024
다양한 입출력 함수

다양한 입출력 함수 send & recv 입출력 함수 윈도우 기반이 아닌 리눅스의 send & recv 함수는 다음과 같다. : 데이터 전송 대상과의 연결을 의미하는 소켓의 파일 디스크립터 전달 : 전송할 데이터를 저장하고 있는 버퍼의 주소 값 전달 : 전송할 바이트 수 전달 : 데이터 전송 시 적용할 다양한 옵션 정보 전달 : 데이터 수신 대상과의 연결을 의미하는 소켓의 파일 디스크립터 전달 : 수신된 데이터를 저장할 버퍼의 주소값 전달 : 수신할 수 있는 최대 바이트 수 전달 : 데이터 수신 시 적용할 다양한 옵션 정보 전달 flags 매개변수에 전달 가능한 옵션 목록 옵션(Option) 의 미 send recv MSG_OOB 긴급 데이터(Out-of-band data)이 전송을 위한 옵션 ⭕️ ⭕ MSG_PEEK 입력버퍼에 수신된 데이터의 존재유무 확인을 위한 옵션 ⭕ MSG_DONTROUTE 데이터 전송과정에서 라우팅(Routing) 테이블을 참조하지 않을 것을 요구하는 옵…

Server
TCP/IP
C
C++
January 19, 2024
IO 멀티플렉싱 기반의 서버(select)

IO 멀티플렉싱 기반의 서버 멀티플렉싱 : 하나의 통신채널을 통해서 둘 이상의 데이터를 전송하는데 사용되는 기술 여기서는 하나의 프로세스로 서비스를 제공하는 것을 말함. select 함수의 이해와 서버의 구현 함수를 이용하는 것이 멀티플렉싱 서버의 구현에 있어서 가장 대표적인 방법이다. 윈도우에도 이와 동일한 이름으로 동일한 기능을 제공하는 함수가 있어 이식성도 좋다. select 함수의 기능과 호출 순서 함수를 사용하면 한곳에 여러 개의 파일 디스크립터를 모아놓고 동시에 이들을 관찰할 수 있다. 이때 관찰할 수 있는 항목은 다음과 같다. 수신한 데이터를 지니고 있는 소켓이 존재하는가? 블로킹되지 않고 데이터의 전송이 가능한 소켓은 무엇인가? 예외상황이 발생한 소켓은 무엇인가? 💡관찰항목 각각을 가리켜 ‘이벤트(event)‘라 한다. 위에서 정리한 관찰항목 각각을 가리켜 이벤트라 하고, 관찰항목에 속하는 상황이 발생했을 때, ‘이벤트(event)가 발생했다’ 라고 표현한다. 이…

Server
TCP/IP
C
C++
January 18, 2024
다중 접속 서버

다중 접속 서버 위 그림에서 보이듯이 클라이언트의 서비스 요청(연결 요청)이 있을 때마다 에코 서버는 자식 프로세스를 생성해서 서비스를 제공한다. 즉, 서비스를 요청하는 클라이언트의 수가 다섯이라면 에코 서버는 추가로 다섯 개의 자식 프로세스를 생성해서 서비스를 제공한다. 이를 위해서 에코 서버는 다음의 과정을 거쳐야 한다. 이것이 기존 에코 서버와의 차이점이다. 1단계 : 에코 서버(부모 프로세스)는 accept 함수호출을 통해서 연결요청을 수락한다. 2단계 : 이때 얻게 되는 소켓의 파일 디스크립터를 자식 프로세스를 생성해서 넘겨준다. 3단계 : 자식 프로세스는 전달받은 파일 디스크립터를 바탕으로 서비스를 제공한다. 다중접속 에코 서버의 구현 함수로 인해 부모 프로세스의 모든 것이 복사된다. 그러나, 소켓은 복사되지 않는다! 소켓을 가리키는 파일 디스크립터만이 복사되었을 뿐이다. 소켓은 프로세스가 아닌 운영체제가 관리하기 때문이다. 하나의 소켓에 두 개의 파일 디스크립터가 …

Server
TCP/IP
C
C++
January 17, 2024
좀비 프로세스

좀비 프로세스 본 포스팅의 내용은 windows os에서 적용되지 않는 linux os의 내용임. 로 생성된 자식 프로세스의 소멸을 위해서는 부모 프로세스가 자식 프로세스의 전달 값을 요청해야 한다. 요청을 위한 구체적인 방법을 이 포스팅에서 설명한다. 좀비 프로세스의 소멸1: wait 함수의 사용 위 함수 호출 시 이미 종료된 자식 프로세스가 있는 경우 : 자식 프로세스가 종료되면서 전달한 값이 매개변수로 전달된 주소의 변수에 저장됨 종료된 자식 프로세스가 없는 경우 : 자식 프로세스가 종료될때까지 블로킹(blocking)됨 블로킹(대기) 상태에서는 CPU 코어를 점유하지 않는다. 자식 프로세스가 종료되면 부모 프로세스는 운영체제로부터 해당 상태를 전달받아 블로킹이 해제된다. 에 저장되는 값은 다음과 같다. : 자식 프로세스가 정상 종료한 경우 TRUE 반환 : 자식 프로세스의 전달 값(return value)을 반환 ⛔️는 statloc 하위 8비트 값만 추출하기 때문에 0~…

Server
TCP/IP
C
C++
January 16, 2024
소켓의 옵션과 입출력 버퍼의 크기

소켓의 옵션과 입출력 버퍼의 크기 소켓의 다양한 옵션 지금까지의 예제들은 매우 간단했기 때문에 특별히 소켓의 특성을 조작할 필요가 없었다. 그러나 소켓의 특성을 변경시켜야만 하는 경우도 흔히 발생한다. 그럼 먼저 다양한 소켓의 옵션 중 일부를 표를 통해 정리해 보이겠다. Protocol Level Option Name Get Set SOL_SOCKET SO_SNDBUF SO_RCVBUF SO_REUSEADDR SO_KEEPALIVE SO_BROADCAST SO_DONTROUTE SO_OOBINLINE SO_ERROR SO_TYPE O O O O O O O O O O O O O O O O X X IPPROTO_IP IP_TOS IP_TTL IP_MULTICAST_TTL IP_MULTICAST_LOOP IP_MULTICST_IF O O O O O O O O O O IPPROTO_TCP TCP_KEEPALIVE TCP_N…

Server
TCP/IP
C
C++
January 16, 2024
IP 주소와 도메인 이름 사이의 변환

IP 주소와 도메인 이름 사이의 변환 도메인 이름을 이용해서 IP 주소 얻어오기 해당 함수는 구조체 변수에 담겨서 반환되는데, 이 구조체는 다음과 같이 정의되어 있다. 위의 구조체 정의를 보니, IP정보만 반환되는 것이 아니라, 여러가지 다른 정보들도 덤으로 반환되는 것을 알 수 있다. 복잡하게 생각하지 않아도 된다. 도메인 이름을 IP로 변환하는 경우에는 만 신경써도 된다. : 공식 도메인 이름(Ofiicial domain name)이 저장된다. : 하나의 IP에 매핑된 다른 여러 도메인 이름의 별칭리스트를 반환한다. : IPv4만 아니라 IPv6도 지원한다. IPv4의 경우는 이 저장된다. : 함수호출의 결과로 반환된 IP주소의 크기가 담긴다. IPv4는 4바이트, IPv6는 16바이트이다. : 이 멤버를 통해서 도메인 이름에 대한 IP주소가 정수의 형태로 반환된다. 접속자가 많은 서버는 여러 IP주소를 둬서 부하를 분산시킨다. gethostbyname 다음은 간단한 예제를 …

Server
TCP/IP
C
C++
January 16, 2024
TCP 기반의 Half-close

TCP 기반의 Half-close TCP에서는 연결과정보다 중요한 것이 중료과정이다. 연결과정에서는 큰 변수가 발생하지 않지만 종료과정에서는 예상치 못한 일이 발생할 수 있기 때문이다. 따라서 종료과정은 명확해야 한다. 일방적인 연결종료의 문제점 리눅스의 함수호출과 윈도우의 함수호출은 완전종료를 의미한다. 완전종료라는 것은 데이터를 전송하는 것은 물론이거니와 수신하는 것 조차 더 이상 불가능한 상황을 의미한다. 때문에 한쪽에서의 일방적인 또는 함수호출은 경우에 따라서 우아해 보이지 못할 수 있다. 위 그림은 양방향을 통신하고 있는 두 호스트의 상황을 묘사한 것이다. 호스트 A가 마지막 데이터를 전송하고 나서 close 함수의 호출을 통해서 연결을 종료하였다. 때문에 그 이후부터 호스트 A는 호스트 B가 전송하는 데이터를 수신하지 못한다. 아니! 데이터 수신과 관련돤 함수의 호출 자체가 불가능하다. 때문에 결국엔 호스트 B가 전송한, 호스트 A가 반드시 수신해야 할 데이터라…

Server
TCP/IP
C
C++
January 15, 2024
UDP기반 서버, 클라이언트 구현

UDP기반 서버, 클라이언트 구현 UDP 서버, 클라이언트는 TCP와 같이 연결된 상태로 데이터를 송수진하지 않는다. 때문에 TCP와 달리 연결 설정의 과정이 필요 없다. 따라서 TCP 서버 구현과정에서 거쳤던 listen 함수와 accept 함수의 호출은 불필요하다. UDP 소켓의 생성과 데이터의 송수신 과정만 존재할 뿐이다. UDP에서는 서버건 클라이언트건 하나의 소켓만 있으면 된다. UDP 기반의 데이터 입출력 함수 : 데이터 전송에 사용될 UDP 소켓의 파일 디스크립터를 인자로 전달 : 전송할 데이터를 저장하고 있는 버퍼의 주소 값 전달 : 전송할 데이터 크기를 바이트 단위로 전달 : 옵션 지정에 사용되는 매개변수, 지정할 옵션이 없다면 0 전달 : 목적지 주소정보를 담고 있는 sockaddr 구조체 변수의 주소 값 전달 : 매개변수 to로 전달된 주소 값의 구조체 변수 크기 전달 TCP 기반의 출력함수와 가장 비교되는 것은 목적지 주소정보를 요구한다는 점이다. : 데이터 …

Server
TCP/IP
C
C++
January 14, 2024
TCP기반 서버, 클라이언트 구현

TCP기반 서버, 클라이언트 구현 TCP 서버에서의 기본적인 함수호출 순서 제일 먼저 socket 함수의 호출을 통해서 소켓을 생성한다. 그리고 주소정보를 담기 위한 구조체 변수를 선언 및 초기화해서 bind함수를 호출하여 소켓에 주소를 할당한다. 이 두 단계는 이미 여러분에게 설명한 내용이니, 이제 그 이후의 과정에 대해서 설명하겠다. 연결요청 대기상태로의 진입(listen) bind 함수호출을 통해서 소켓에 주소까지 할당했다면, 이번에는 listen 함수호출을 통해서 ‘연결요청 대기상태’로 들어갈 차례이다. 그리고 listen 함수가 호출되어야 클라이언트가 연결요청을 할 수 있는 상태가 된다. 즉, listen 함수가 호출되어야 클라이언트는 연결요청을 위해서 connect 함수를 호출할 수 있다. : 연결요청 대기상태에 두고자 하는 소켓의 파일 디스크립터 전달, 이 함수의 인자로 전달된 디스크립터의 소켓이 서버 소켓(리스닝 소켓)이 된다. : 연결요청 대기 큐(Queue)의 …

Server
TCP/IP
C
C++
January 13, 2024
주소 체계와 데이터 정렬

주소 체계와 데이터 정렬 주소정보의 표현 이 구조체는 함수에 구조체를 전달하는 용도로 사용된다. POSIX 이나 내부의 구조체에는 생소한 자료형이 있다. 이들은 POSIX 표준에 정의되어 있다. (확장성을 고려)      자료형 이름                          자료형에 담길 정보                     선언된 헤더파일 int8_t uint8_t int16_t uint16_t int32_t uint32_t signed 8-bit int unsigned 8-bit int (unsigned char) signed 16-bit int unsigned 16-bit int (unsigned short) signed 32-bit int unsigned 32-bit int (unsigned long) sys/types.h sa_family_t socklen_t 주소체계(address family) 길이정보(length of struct) sy…

Server
TCP/IP
C
C++
January 13, 2024
소켓의 타입과 프로토콜의 결정

소켓의 타입과 프로토콜의 결정 소켓의 생성 : 소켓이 사용할 프로토콜 체계(Protocol Family) 정보 전달 : 소켓의 데이터 전송방식에 대한 정보 전달 : 두 컴퓨터간 통신에 사용되는 프로토콜 정보 전달 프로토콜 체계(Protocol Family) 이름                               프로토콜 체계(Protocol Family)                               PF_INET IPv4 인터넷 프로토콜 체계 PF_INET6 IPv6 인터넷 프로토콜 체계 PF_LOCAL 로컬 통신을 위한 UNIX 프로토콜 체계 PF_PACKET Low Level 소켓을 위한 프로토콜 체계 PF_IPX IPX 노벨 프로토콜 체계 소켓의 타입 연결지향형 소켓(SOCK_STREAM) 중간에 데이터가 소멸되지 않고 목적지로 전송된다. 전송 순서대로 데이터가 수신된다. 전송된 데이터의 경계가 존재하지 않는다. 데이터를 전송하는 컴퓨터가 세 번의 write…

Server
TCP/IP
C
C++
January 12, 2024
네트워크 프로그래밍과 소켓의 이해

네트워크 프로그래밍과 소켓의 이해 소켓의 전화기에의 비유 OS의 소켓은 전화기에 비유할 수 있다. 서버 비유 함수 반환 전화기의 장만 성공 시 파일 디스크립터, 실패 시 -1 전화번호의 부여 성공 시 0, 실패 시 -1 전화 케이블에 연결 성공 시 0, 실패 시 -1 수화기를 들기 성공 시 파일 디스크립터, 실패 시 -1 클라이언트          비유          함수                  반환                  전화 걸기 성공 시 0, 실패 시 -1 서버 프로그램의 구현 클라이언트 프로그램의 구현 Linux기반 파일(소켓) 조작하기 💡 리눅스는 “모든 것은 파일이다”라는 철학을 가지고 있어서, 파일과 소켓을 포함하여 다양한 자원을 파일로 취급함. 리눅스에서는 소켓을 파일처럼 다루기 때문에, 파일 입출력과 동일하게 조작할 수 있다. 명칭 리눅스 : 파일 디스크립터 윈도우 : 파일 핸들 표준 입출력 및 표준 에러 파일 디스크립터 파일 디스크립터 대…