728x90

Event 오브젝트 기반의 입출력 완료 확인

- IO가 완료됐는지 확인하기 위해 Send/Recv 시 Overlapped에 event 오브젝트 등록

- WSAWaitMultipleEvent를 통해 Overlapped의 event가 signaled 상태가 되는 것을 대기

- WSAGetOverlappedResult를 통해 결과를 확인

{
	evObj=WSACreateEvent();
	memset(&overlapped, 0, sizeof(overlapped));
	overlapped.hEvent=evObj;
	dataBuf.len=BUF_SIZE;
	dataBuf.buf=buf;
    
	if(WSARecv(hRecvSock, &dataBuf, 1, &recvBytes, &flags, &overlapped, NULL)
		==SOCKET_ERROR)
	{
		if(WSAGetLastError()==WSA_IO_PENDING)
		{
			WSAWaitForMultipleEvents(1, &evObj, TRUE, WSA_INFINITE, FALSE);
			WSAGetOverlappedResult(hRecvSock, &overlapped, &recvBytes, FALSE, NULL);
		}
		else
		{
			printf("WSARecv() error");
		}
	}
}

 

Completion Routine 기반의 입출력 완료 확인

- IO가 완료됐을 때 운영체제에 의해 호출되는 함수

- Completion Routine이 호출되기 위해서는 해당 쓰레드가 alertable wait 상태여야 함

- alertable wait : 운영체제가 전달하는 메세지 수신이 가능한 특별한 일이 진행하지 않은 상태

- alertable wait 상태로 진입하기 위핸 아래 함수가 사용

     -> WaitForSingleObjectEx, WaitForMultipleObjectEx, WSAWaitForMultipleEvents, SleepEx

typedef void (CALLBACK *LPWSAOVERLAPPED_COMPLETION_ROUTINE)(DWORD dwError,DWORD cbTransferred,
							LPWSAOVERLAPPED lpOverlapped,DWORD dwFlags);

    -> dwError : 오류 정보. 정상 시 0 전달

    -> cbTransferred : 완료된 입출력 데이터의 크기정보

    -> lpOverlapped : WSASend, WSARecv 시 전달한 Overlapped 구조체 값

    -> dwFlags : WSASend, WSARecv 시 전달한 특성정보 값

{
	memset(&overlapped, 0, sizeof(overlapped));
	dataBuf.len=BUF_SIZE;
	dataBuf.buf=buf;
	evObj=WSACreateEvent();     
    // completion routine을 사용할거지만 쓰레드를 alertable wait 상태로 바꾸기 위한
    // WSAWaitForMultipleEvents에 사용할 더미 event 오브젝트

	if(WSARecv(hRecvSock, &dataBuf, 1, &recvBytes, &flags, &overlapped, CompRoutine)
		==SOCKET_ERROR)
	{
		if(WSAGetLastError()==WSA_IO_PENDING)
			puts("Background data receive");
	}

	idx=WSAWaitForMultipleEvents(1, &evObj, FALSE, WSA_INFINITE, TRUE);
	if(idx==WAIT_IO_COMPLETION)
		puts("Overlapped I/O Completed");
	else    // If error occurred!
		ErrorHandling("WSARecv() error");
}

void CALLBACK CompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags)
{
	if(dwError!=0)
	{
		printf("CompRoutine error");
	}
	else
	{
		printf("Received message: %s \n", buf);
	}
}

 

728x90

+ Recent posts