본문 바로가기
VisualStudio.C++.C#

MFC. CSocket. 소켓통신 구현

by i.got.it 2019. 5. 12.

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

 

Berkeley Socket

개요 Berkeley Sockets : 네트웍 포함 프로세스간 통신(IPC: Inter Process Communication) 위한 아래 그림의 구조를 갖는 API. - Berkeley Sockets 구조/작동방식은 Windows, POSIX, Linux에서의 Sockets API 등..

igotit.tistory.com

 

 

 

 

 


첫등록 : 2019년 5월 11일 

최종수정 : 

 

본 글 단축주소 : https://igotit.tistory.com/2158

 


 

댓글



 

비트코인




암호화폐       외환/나스닥/골드         암호화폐/외환/나스닥/골드
     
현물 |선물 인버스 |선물 USDT       전략매니저(카피트레이딩)         프랍 트레이더 온라인 지원가능. MT4,MT5