728x90

IO의 중첩

- 둘 이상의 IO를 동시에 진행

- 데이터의 전송을 중첩시키기 위해서는 넌-블로킹 모드(비동기 IO)로 동작

 

Overlapped IO

- 윈도우에서 IO를 중첩시키는 입출력 모델

- Overlapped IO의 소켓 생성 : WSASocket

    -> dwFlags : 소켓의 속성 정보 전달. WSA_FALG_OVERLAPPED(0x01) 상수 전달

SOCKET WSASocket(int af,int type,int protocol,LPWSAPROTOCOL_INFOW lpProtocolInfo,GROUP g,DWORD dwFlags);

- Overlapped IO 데이터 전송 : WSASend

    -> lpOverlapped : WSAOVERLAPPED 구조체 전달. EVENT 오브젝트를 사용해서 데이터 전송 완료를 확인할때 사용

    -> lpCompletionRoutine : 함수 포인터를 전달해서 데이터 전송 완료 시 함수 호출됨

int WSASend(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesSent,DWORD dwFlags,
		LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
{        
        WSAEVENT evObj;
        WSAOVERLAPPED overlapped;
        WSABUF dataBuf;
        char msg[]="Network is Computer!";
        evObj=WSACreateEvent();
        memset(&overlapped, 0, sizeof(overlapped));

        overlapped.hEvent=evObj;        // Event 오브젝트 전달
        dataBuf.len=strlen(msg)+1;
        dataBuf.buf=msg;

        if(WSASend(hSocket, &dataBuf, 1, &sendBytes, 0, &overlapped, NULL)==SOCKET_ERROR)
        // overlapped 구조체를 전달해서 데이터 전송 완료 시 overlapped 안의 hEvent 상태가 바뀜
}

- Overlapped IO 데이터 수신 : WSARecv

    -> WSASend와 유사

int WSARecv(SOCKET s,LPWSABUF lpBuffers,DWORD dwBufferCount,LPDWORD lpNumberOfBytesRecvd,LPDWORD lpFlags,
	LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);

- 데이터 송수신 결과 확인 : WSAGetOverlappedResult

    -> lpOverlapped : IO 진행 시 전달한 WSAOVERLAPPED 구조체

    -> lpchTransfer : 실제 송수신된 바이트의 크기

    -> fWait : IO가 진행중인 경우 TRUE 전달 시 완료될때까지 대기, FALSE 전달 시 FALSE 반환

    -> lpdwFlags : 부수적인 정보를 얻기 위해(MSG_OOB)를 얻기 위해 사용 불필요시 NULL 전달

BOOL WSAGetOverlappedResult(SOCKET s,LPWSAOVERLAPPED lpOverlapped,LPDWORD lpcbTransfer,
			WINBOOL fWait,LPDWORD lpdwFlags);

- 데이터가 전송중인 상태라면 SOCKET_ERROR가 발생되기 때문에 실제 오류가 아닌지는 WSAGetLastError를 통해 에러를 확인해서 WSA_IO_PENDING인지를 체크

{
    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");
		}
	}
}
728x90

+ Recent posts