2015. 5. 17. 01:27ㆍ프로그래밍/서버
특징
- 비동기 데이터 송수신을 할 수 있다.
- 소켓 내부 버퍼를 사용하지 않고 직접 TCP 전송 버퍼에서 데이터를 본재고 받을 수 있다.
비동기 송수신, WSAAsyncSelect Model vs Overlapped I/O Model
WSAAsyncSelect
데이터를 송수신 하면서 다른 일을 할 수 있다고 생각할 수 있지만
윈도우 메시지가 왔을 때 send(), recv()를 통해 데이터를 송수신 한다.
프로그래머가 직접 데이터를 송수신 하겠다는 의미이다.
Overlapped I/O
커널에 데이터를 송수신 하겠다고 요청을 하고나서 따로 데이터를 송수신을 할 필요가 없다.
WSASend()나 WSARecv()를 이용해 Overlapped I/O로 데이터를 송수신 하는 것이다.
한 마디로 커널이 직접 데이터를 송수신하고 그 결과를 프로그래머에게 알려주는 것이다.
소켓 내부 버퍼를 사용하지 않는 것
기본적으로 설정되는 특징은 아니다. 소켓 옵션 함수를 이용해 소켓 내부 버퍼를 0으로 만들어 주어야 가능하다.
소켓 전송 버퍼가 0이면 TCP에 직접 전송한다. 메모리 복사를 한 번 줄여주는 것이 엄청난 성능 향상!
소켓 전송 버퍼를 0으로 했을 때 주의해야 할 점
TCP 수신 버퍼에서 바로 가져올 수 있도록 충분한 수의 Overlapped I/O 호출을 미리 해야 한다.
- Overlapped I/O 호출을 미리 하지 않으면 TCP 수신 버퍼로 들어오는 데이터양이 사용자 버퍼로
읽어 들이는 양보다 많아져 TCP 수신 버퍼가 금방 다 차서 상대방에 데이터를 보내지 못하는 경우가 생긴다.
TCP 송신 버퍼에서 내보내는 데이터양보다 사용자 TCP 송신 버퍼로 보내는 데이터양이 많아
사용자 버퍼에서 TCP 송신 버퍼로 복사되기 전까지 그 사용자 버퍼를 사용할 수 없다는 것이다.
Overlapped I/O 사용시 주의 점
데이터를 보낼 때는 데이터 송신 작업이 완료될 때까지 데이터가 들어있는 사용자 버퍼를 삭제해선 안된다.
WSASend, WSARecv 함수 분석
인자
SOCKET s - 데이터를 보낼 연결된 소켓
LPWSABUF lpBuffer - WSABUF 구조체 변수에 보낼 데이터의 크기와 데이터를 채우고 변수의 포인터를 인자로 넣는다.
DWORD dwBufferCount - 버퍼의 개수를 넣는다. 두 번째 인자로 넣은 WSABUF 구조체의 배열 개수를 넣으면 된다.
DWORD flag - send(), recv()와 동일
LPWORD lpNumberOfBytesSent
LPWSAOVERLAPPED lpOverlapped
- 가장 중요한 역할을 한다.
WSAOVERLAPPED 구조체 분석
DWORD Internal
DWORD InternalHigh
DWORD Offset
DWORD OffsetHigh
내부적으로 사용하는 변수들. 0으로 초기화. <- 이건 나중에 좀 더 알아보자..
WSAEVENT hEvent
- 이벤트 객체의 핸들로써 Overlapped I/O 요청이 완료되었다는 것을 알려주는 역할을 한다.
LPWSAOVERLAPPED _COMPLETION_ROUTINE lpCompletionROUTINE
- 완료 루틴에 대한 포인터를 받는다.
완료 루틴이란? Overlapped I/O가 완료되면 호출되는 콜백 함수를 말한다.
함수의 반환 값이 0이면 Overlapped I/O 요청이 즉시 완료 되어 함수 호출이 성공했다는 것을 의미.
0이 아니라면 GetLastError() 함수를 이용하면 WSA_IO_PENDING 인지 확인한다.
에러 코드가 이것이라면 요청한 Overlkapped I/O가 즉시 처리 되지 않고 나중에 처리 된다는 의미!!
WSA_IO_PENDDING이 아니라면 함수 호출에 실패한 것.
Scatter-Gatter I/O
우리말로 풀면 분배-집합 입출력. WSASend() 함수를 이용하여 여러 개의 버퍼를 하나의 패킷으로 묶어 보내고
받는 쪽에선 WSARecv() 함수를 이용하여 하나의 패킷으로 받아서 다시 여러 개의 버퍼로 나눌 수 있다.
일반적으로 고정되고 형식화된 데이터를 송수신 하는 프로그램에서는 유용하지만 게임 서버에서는 거의 쓰지 않는다.
'프로그래밍 > 서버' 카테고리의 다른 글
동기화 (0) | 2015.07.23 |
---|---|
Thread (0) | 2015.07.23 |
Blocking vs Non-Blocking (0) | 2015.07.12 |
[서버] 데드 레커닝(Dead Reckoning) (1) | 2015.05.23 |
IOCP 정리 (0) | 2015.05.14 |
TCP/IP 프로토콜 개요 (1) | 2015.04.27 |
메모리 풀(Memory Pool) (0) | 2015.03.18 |