Program/C & C++

MFC를 이용한 범용 소켓을 이용한 예제

너구리V 2011. 7. 13. 23:12
먼저 Stdafx.h 맨 아래 줄에


#include "afxsock.h"

추가한다.

InitInstance() 함수에

CWinApp::InitInstance();
if (!AfxSocketInit()) {
  AfxMessageBox(_T("소켓 초기화 실패"));
  return FALSE;
}
...

추가한다. 그런 다음

#include "ServerSocket.h"
#include "DataSocket.h"

...

// 멤버 변수로 선언
CServerSocket m_ServerSocket;
CDataSocket m_DataSocket;
...
// ServerSocket 초기화
m_ServerSocket.Init(this, 2000);
...

// 메시지 처리기 만들어야 함, 헤더 파일에 다음 추가
afx_msg LRESULT OnAccept(WPARAM wParam, LPARAM lParam);

// 소스 파일에 다음 추가
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
  ...
    ON_MESSAGE(UM_ACCEPT, OnAccept)
END_MESSAGE_MAP()

LRESULT CTestDlg::OnAccept(WPARAM wParam, LPARAM lParam) {
  // 연결을 받아 들이고 클라이언트와 m_DataSocket을 연결
    if (!m_ServerSocket.Accept(m_DataSocket) {
        AfxMessageBox(_T("Accept 실패"));
      return 0;
  }

  // 데이터 소켓 초기화
    m_DataSocket.Init(this);

  // Do something
    m_ctrlListBox.AddString(_T("연결되었습니다."));
  return 0L;
}

// 여기 부터 클라이언트 기능

if (!m_DataSocket.Create()) {
  AfxMessageBox(_T("클라이언트 소켓 생성 실패"));
  return;
}
// 접속 요청
if (!m_DataSocket.Connect(sIpAddress, 2000)) {
  AfxMessageBox(_T("서버 접속 실패"));
  return;
}
// 클라이언트 소켓 초기화
m_DataSocket.Init(this);
// Do something
...

CEdit에서 상속받은 CEnterNotifyEdit 클래스 만든다
WM_CHAR 메시지의 처리기를 재정의하여 [Enter] 키가 눌릴 때마다 메시지를 보내도록 한다.
먼저 리소스 기호 메뉴 선택 > 리소스 기호 대화상자에서 새로운 기호로 등록한다.

void CEnterNotifyEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
  if (nChar == VK_RETURN)
        GetParent()->SendMessage(WM_COMMAND, ID_ENTERKEY, 0);
  CEdit::OnChar(nChar, nRepCnt, nFlags);
}

CEnterNotifyEdit을 다이얼로그에 추가 후
헤더파일에 메시지 처리기 추가한다.

afx_msg void OnEnterKey();

함수 몸체에서

BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
  ...
    ON_COMMAND(ID_ENTERKEY, OnEnterKey)
END_MESSAGE_MAP

// Data 송신
void CTestDlg::OnEnterKey() {
  UpdateData();
  // 데이터 전송
    CData data;
  data.m_strData = m_strEdit;
  m_DataSocket << data;

  //전송된 문자열을 표시
&nbsp;   ...
&nbsp;   // Edit 컨트롤 초기화 ...
&nbsp;   UpdateData(FALSE);
}

// Data 수신
똑같이 헤더파일에 다음 추가
afx_msg LRESULT OnReceive(WPARAM wParam, LPARAM lParam);

다시 본체에

BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
  ...
&nbsp;   ON_MESSAGE(UM_DATARECEIVE, OnReceive)
END_MESSAGE_MAP()

LRESULT CTestDlg::OnReceive(WPARAM wParam, LPARAM lParam) {
  // 통신 버퍼에 있는 데이타를 전부 수신할 때까지...
&nbsp;   do {
&nbsp;   &nbsp;   // 데이타 수신
&nbsp;   &nbsp;   CData data;
  &nbsp;   m_DataSocket >> data;

  &nbsp;   // 수신된 데이타 표시
&nbsp;   &nbsp;   ...
&nbsp;   } while (!m_DataSocket.m_pArchiveIn->IsBufferEmpty());
  return 0L;
}

...

휴 ...

>>, << 를 이용해서 데이타 송수신하고do, while을 이용해서 열심히 수신해야 한다.
데이타를 받고 나서도 OnReceive함수가 그때 그때 호출되는 것이 아니라서 이렇게 해야함

반응형

'Program > C & C++' 카테고리의 다른 글

[MFC] Thread를 이용한 TCP기반 Receive()함수 구현  (0) 2011.07.17
MFC UI 꾸미기  (0) 2011.07.15
MFC를 이용한 범용 서버 소켓 작성  (0) 2011.07.13
COleDateTime Class  (0) 2011.07.13
Open CV  (0) 2011.04.11