MFC 소켓 클래스 개요.
MFC 에서 제공하는 소켓관련 클래스는 CAsyncSocket 과 CSocket 이 있다.
윈속API 를 갭슐화 한것이 CAsyncSocket 이며 CAsyncSockt 을 베이스 클래스로 한 것이 CSocket 이다.
- CAsyncSocket 은 non-blocking(~비동기) 방식, CSocket 은 blocking(~동기) 방식.
- CScoket 을 이용하는 경우에도 통상적인 소켓 송수신 함수인 Send/Receive 함수 호출하여 구현가능하나, CSocket 이용시에는 CSocketFile을매개로 하여 CArchive 클래스를 이용하여 데이터 송수신을 보다 간결하게 구현가능하다.
- - 즉, CArchive <-> CSocketFile <-> CSocket MFC 구조.
코드 구성
소켓통신은 소켓서버측과 소켓클라이언트측 으로 구분되고, 소켓서버측은 클라이언트 요청시 해당 클라이언트와 통신 전담하는 "소켓을 생성하여 상대방(클라이언트) 소켓과 통신"게된다. 앞의 문장에서 밑줄친 부분은 클라이언트측에도 동일하게 요구되는 기능이어서 이 기능을 하는 클래스 (예 CCySocketCore) 를 구현하면 이것 자체로 소켓클라이언트기능이 구현되고 동시에 소켓서버측에서도 이 클래스를 그대로 활용가능하다.
소켓클래스 사용하기 위한 필수 처리사항.
프로젝트생성시 위저드에서 Supprt Socket 을 선택하지 않은 경우 아래예와 같이 App의 Initinstance 에 AfxSocketInit() 함수 추가한다. 함수 AfxSocketInt 은 afxsock.h 에서 정의되고 있다.
#include <afxsock.h> /// stdafx.h or framework.h( VC++2019 )
///////////
BOOL CCyFinForecastApp::InitInstance()
{
CWinApp::InitInstance();
if (!AfxSocketInit())
{
AfxMessageBox(_T("AfxSocketInit() FAILED. InitInstance"));
}
return TRUE;
}
CCySocketCore 구현. 소켓클라이언트
- 기능 : 소켓클라이언트, 소켓서버측에서도 소켓서버 기능에 부가되어 소켓생성및 클라이언트와의 통신담당.
- 구현상황 : 메인프로젝트 CCyFinDevice 라는 프로젝트에 소켓기능 추가.
- 베이스 클래스 : CSocket
- 송수신 함수 : CArchive 기반 시리얼라이징 데이터 송수신.
단계1.CCySocketCore 생성.
동영상. 클래스 위저드로 CSocket 을 베이스 클래스로 선택하여 생성과정.
단계2. CCySocketCore 인스턴스 생성, Create, Connect
앞에서 생성한 클래스 CCySocketCore 를 활용할 곳에서 아래 코드와 같은식으로 소켓생성하고 소켓서버 접속 시도. Create 와 Connect 는 모두 CSocket 에서 제공되는 함수임.
CCySocketCore m_CySocketClient; // instance
////////////
m_CySocketClient.Create(); // Ctreation Socket.
m_CySocketClient.Connect(_T("127.0.0.1", 9090)); // ip address and port
단계3. 이벤트 핸들러 함수들 오버라이딩 하기.
OnClose : 상기 단계2에서와 같이 접속명령으로 성공적으로 접속되었다고 해도 서버측의 사유등으로 접속이 끊기는 것 처리 하기 위함.
OnReceive : 새로운 데이터가 수신되었을때 발생.
단계4. 데이터 클래스 CCySocketDataT1
CArchive 기반 데이터 전송위하여 데이터 정의용 클래스. 필수 CObject 를 베이스 클래스로 해야한다.
동영상. - CCySocketDataT1 생성하고 Serialize 오버라이딩 하고, 실제 통신에서 사용할 변수 선언하고 Serialize 함수내에서 데이터 변수들 처리 과정 전체.
- 필요에 따라 데이터 클래스는 임의로 여러개 정의가능하다. 수신용과 송신용을 다르게 정의해도 된다.
단계5. 데이터 송신 구현/시험.
데이터 송신 함수를 아래 처럼 정의 하고,
int CCySocketCore::SocketSendData(CCySocketDataT1* p_data_send)
{
if (m_pArchiveOut != NULL)
{
p_data_send->Serialize(*m_pArchiveOut);
m_pArchiveOut->Flush();
}
return 1;
}
시험용으로 데이터 생성된 임의 장소에서 상기 함수 호출(아래 코드) 하여 소켓서버쪽에 데이터 전송되는지 확인.
//// test data send to socket
CCySocketDataT1 sock_data_send;
sock_data_send.price_ask = price_ask;
sock_data_send.price_bid = price_bid;
m_pDlg->m_CySocketClient.SocketSendData(&sock_data_send);
통신 시험.
동영상1 - 소겟서버로 파이썬 소켓서버 이용하여 시험. -소켓서버측에서 수신데이터를 hex 로 출력하는 경우.
CCySocketServer 구현. 소켓서버
단계1. CCySocketServer클래스 생성.
- CSocket 을 베이스 클래스로 하여 CCySocketServer 생성.
- 소켓클라이언트 측의 접속요청 이벤트 OnAccept 오버라이딩.
단계2. Init 함수 추가하고 Create, Listen , OnAccept 처리.
void CCySocketServer::Init(CWnd* pWnd, int n_portnum)
{
m_pWnd = pWnd;
Create(n_portnum);
Listen(); // 접속요청 감지개시.
}
- OnAccept 에서는 실처리없이 m_pWnd 로 메시지 전송하여 다른곳에서 처리 수행.
#define UM_ACCEPT_CCYSOCKETSERVER (WM_USER+10)
void CCySocketServer::OnAccept(int nErrorCode)
{
m_pWnd->SendMessage(UM_ACCEPT_CCYSOCKETSERVER);
// TODO: Add your specialized code here and/or call the base class
CSocket::OnAccept(nErrorCode);
}
소켓 서버 클라이언트 기본개념 : https://igotit.tistory.com/820
첫등록 : 2019년 5월 11일
최종수정 :
본 글 단축주소 : https://igotit.tistory.com/2158
'VisualStudio.C++.C#' 카테고리의 다른 글
Visual Studio 연도 버전별 솔루션 파일만 보고 버전 확인 방법 (0) | 2019.10.27 |
---|---|
MFC. Serialize. 직렬화. (0) | 2019.05.14 |
Visual Studio Code 에서 MQL 문법 하이라이팅. (2) | 2019.04.30 |
VC++, DLL 활용하는법.- implicit linking (암시적 연결방식) (0) | 2019.04.16 |
VC++. MFC 대화상자 기반 응용프로그램 만들기.예: CyFinAPI_App1 (0) | 2019.04.16 |
댓글