Transcript 23장

서버
동작원리
1. 클라이언트가 연결되면 WSARecv함수를 호출하면서 넌-블로킹 모드로 데이터가 수
2. 수신이 완료되면 ReadCompRoutine함수가 호출
3. ReadCompRoutine함수가 호출되면 WSASend 함수를 호출하면서 넌-블로킹 모드로
송신
4. 송신이 완료되면 WriteCompRoutine함수가 호출
5. 호출된 WriteCompRoutine함수는 다시 WSARecv함수를 호출하면서 넌-블로킹 모드
수신을 기다림
입출력 완료 시 자동으로 호출되는 Completion Routine 내부로 클라이언트 정보(소켓
전달하기 위해서 WSAOVERLAPPED 구조체의 멤버 hEvent를 사용
클라이언트 구현
tcp의 전송특성(경계가 존재 안 함)을 고려해서 수신해야 할 데이터가 완전히 수신될
recv함수 반복 호출
클라이언트
int main()
{
while(1)
{
fgets(message, BUF_SIZE, stdin);
strLen = strlen(message);
send();
while(1)
{
}
}
}
readLen += recv();
if(readLen >= strLen)
break;
int main
{
CreateIoCompletionPort(); //CP 오브젝트 생성
for(i=0; i<sysInfo.dwNumberOfProcessors; i++) //코어의 수만큼 쓰레드 생성
_beginthreadex(~, (void *) hComPort, ~); //쓰레드 생성
CreateIoCompletionPort(); //CP 오브젝트와 소켓, 소켓정보를 연결
ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA)); //입출력 정보 생성
}
WSARecv(); //소켓과 입출력정보 연결 및 입출력시작
쓰레드
DWORD WINAPI EchoThreadMain(void * pComport)
{
GetQueuedCompletionStatus(); //입출력이 완료된 CP 오브젝트, 소켓정보,
입출력정보 얻음
if(ioInfo->rwMode==READ) // 얻은 입출력정보에 따른 처리
{
}
else if(ioInfo->rwMode == WRITE) // 얻은 입출력정보에 따른 처리
{
}
OS
CP
오브젝트
소켓
소켓정보 Io정보
소켓
소켓정보 Io정보
소켓
소켓정보 Io정보
입출력 완료
입출력이 완료된 소켓
소켓
소켓정보 Io정보
소켓
소켓정보
1. CreateIoCmpletionPort함수
소켓과 cp오브젝트, 소켓정보를 연결
소켓
소켓정보 Io정보
입출력 완료
CP
오브젝트
소켓
소켓정보 Io정보
2. WSARecv함수
송수신 시작 및 송수신에 대한 정보
Io정보를 소켓에 연결
3. GetQueuedCompletionStatus함수
송수신이 완료된
CP오브젝트, 소켓정보, IO정보를 얻
WSARecv(handleInfo->hClntSock, &(ioInfo->wsaBf), 1 &recvBytes, &flags,
&(ioInfo->overlapped), NULL);
WSARecv 함수를 호출하면서 일곱 번째 인자로 OVERLAPPED 구조체 변수의 주소 값을 전
이 값은 이후에 GetQueued… 함수가 반환을 하면서 얻을 수 있다 그런데 구조체 변수의 주
첫 번째 멤버의 주소 값과 동일하므로 PER_IO_DATA 구조체 변수의 주소 값을 전달한 것과
GetQueuedCompletionStatus(hComPort, &bytesTrans, (LPDWORD)&handleInfo,
(LPOVERLAPPED*) &ioInfo, INFINITE);
포인터 iofo에 저장된 값은 OVERLAPPED 구조체 변수의 주소 값이지만, PER_IO_DATA 구조
주소 값이기도 하다. 따라서 멤버 rwMode에 저장된 값의 확인을 통해서 입력의 완료인지
완료인지를 확인하고 있다