본문 바로가기
Programming

MFC 메세지 처리, MFC winsock 비동기 방식

by 단창 2011. 12. 1.


MFC를 기초지식 없는 상태로 구글링 만으로 해결하고 있다.
MFC 사용법 정도야 웹에 널리고 널렸으니, 안될거야 없지만 원하던 딱 그 내용들이 한방에 검색되는게 아니다 ㅠㅠ 도서관에서 책이나 하나 빌려야 겠다.. 싶지만 이틀간의 무한삽질결과 만들려고 했던것은 해결했으니 그냥 넘어가야지 .. ㅠㅠ  구글링에서 얻었으니 정리해서 구글사회에 환원해 보자.


1. MFC의 비동기 소켓방식
  QT를 먼저 쓰고 있다가 갑자기 MFC를 하려니 걸리는게 왜 이렇게 많니.. 결국엔 QT의 signal, slot과 별반 다르지 않았다.
MFC 에선 이벤트가 발생하면, 그것을 처리할 핸들러 함수를 정해 주는 식인데, (QT의 장점이 signal-slot 방식이라고 알고 있는데, MFC랑 문법만 다르지, QT가 독창적인게 뭘까? -_- ? signal-slot 으로 객체간 연결이 좀더 간편해 진다는 정도??)
처리할 이벤트의 지정은
listen(~~~~ )을 시전하고 소켓을 만든후에,

WSAAsyncSelect(clientsock,hWnd,WM_SOCKET,(FD_CLOSE|FD_READ|FD_ACCEPT));
를 이용해서 한다.

인자를 살펴보면,
1번째 인자, clinetsock = 사용할 소켓,
2번째 인자, hWnd = 해당하는 윈도우의 핸들
3번째 인자, WM_SOCKET = 내가임의로 정해준 ID, 이전에 #define WM_SOCKET WM_USER+1 이라고 지정해 놓았다. 이 ID가 여러 메세지 핸들링 함수를 찾아가는 지침표가 된다.
4번째 인자가 처리할 메세지들인데 | 로 겹쳐 놨으니, 이 세가지의 이벤트 가 발생할때, 핸들링 함수가 호출된다.


요약하면 "clinetsock에 FD_CLOSE, FD_READ, FD_ACCEPT 이벤트가 발생하면 hWnd 윈도우로 WM_SOCKET(임의의 ID)에 해당하는 메세지를 보내줘라!" 가 되겠다.

FD_ACCECT : 소켓이 연결하려고 들어올때
FD_READ : 버퍼에 읽을 데이터가 있을때
FD_CLOSE : 소켓이 disconnect 될때


그리고 메세지 테이블을 작성해 준다.  (cpp 에 위치함)
BEGIN_MESSAGE_MAP(~~~~~~)
 //{{AFX_MSG_MAP(CKeyexeDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_MESSAGE(WM_KEYSTROKE, processkey)
 ON_MESSAGE(WM_SOCKET, socket_handler)
 ON_WM_TIMER()
 ON_WM_CANCELMODE()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

이렇게 처리할 메세지를 적어준다. socket_handler는 내가 정의한 핸들링 펑션

그리고, 이 함수의 선언은
LRESULT CTestServerDlg::OnServerSocketMessage(WPARAM wParam,LPARAM lParam)
이라고 해준다.

파라미터는            
- WPARAM wParam : 현재 32bit 소켓의 핸들러
- LPARAM lParam : 상위 16bit(Event), 하위 16bit(Error여부) 라고 한다.


실제 이벤트 함수에서는 들어오는 Message에 따라 switch case 로 해결해주면된다.

LRESULT CKeyexeDlg::socket_handler(WPARAM wParam,LPARAM lParam)

 switch(WSAGETSELECTEVENT(lParam))
{

 case FD_READ:

~~~~~

 case FD_CLOSE:
 case FD_ACCEPT:

 }
}

이런식으로!! ㅎㅎ

반응형