일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- public
- mfc
- atmega328
- Encapusulation
- stream
- Binary
- inheritance
- Pointer
- SERIAL
- Unity
- parameter
- length
- Overloading
- sensor
- java
- wpf
- Android
- memory
- flutter
- Read
- aduino
- APP
- UNO
- file access
- digitalRead
- Class
- Contour
- preprocessing
- Barcode
- compare
- Today
- Total
폴크(FOLC)
MFC 테크닉 - 통신 WinSock ( Client ) 본문
# CSocket 을 사용하면서 OnReceive(), OnClose() 함수가 정상적으로 호출이 발생하지 않는 상황
> 윈속 으로 직접 만들어서 데이터 송/수신
> 통신 event 가 발생한 경우에만 데이터 연동
# 윈속 사용하기 위해서 필요한 내용
> #include <afxsock.h> // MFC 소켓 확장
> AfxSocketInit();
# 소스 코드 내용
CString m_strServerIP = _T("127.0.0.1");
int m_nServerPort = 7000;
// 윈속 초기화
WSADATA wsa;
int ret = WSAStartup(MAKEWORD(2, 2), &wsa);
if(ret != NO_ERROR)
{
//wprintf(_T("WSAStartup function failed with error : %d\n"), iResult);
return;
}
// 소켓 생성
SOCKET client_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(m_sock == INVALID_SOCKET)
{
//wprintf(_T("socket function failed with error : %ld\n"), WSAGetLastError());
WSACleanup();
return;
}
// 소켓 연결
char ipaddress[20];
WideCharToMultiByte(CP_ACP, 0, m_strServerIP, -1, ipaddress, 20, NULL, NULL);
SOCKADDR_IN serveraddr;
serveraddr.sin_family = AF_INET;
inet_pton(AF_INET,ipaddress,&serveraddr.sin_addr.s_addr);
serveraddr.sin_port = htons((unsigned short)m_nServerPort);
int ret = connect(client_sock, (SOCKADDR*)&serveraddr, sizeof(serveraddr));
if (retval == SOCKET_ERROR)
{
//wprintf(_T("connect function failed with error: %ld\n"), WSAGetLastError());
}
else
{
// 서버와 데이터 통신
WSAEVENT hMesgSocketEvent = WSACreateEvent();
WSAEventSelect(client_sock, hMesgSocketEvent, FD_READ | FD_CLOSE);
while (1)
{
if(ReceiveDataFromServer(hMesgSocketEvent) == false) break;
}
}
# Receive 관련 소스 내용 ( 데이터 수신 )
bool ReceiveDataFromServer(WSAEVENT hMesgSocketEvent)
{ // 네트워크 이벤트
WSANETWORKEVENTS NetworkEvents;
if (WSAEnumNetworkEvents(client_sock, hMesgSocketEvent, &NetworkEvents) != SOCKET_ERROR)
{
if ((NetworkEvents.lNetworkEvents & FD_READ) == FD_READ)
{
if (NO_ERROR == NetworkEvents.iErrorCode[FD_READ_BIT]) // 데이터 받기
{
int nTotalBytes = 1024;
std::vector<char> vecTotalBytes(nTotalBytes);
char *pszRecvData = &vecTotalBytes[0];
ZeroMemory(pszRecvData, nTotalBytes);
int nBytesRecv = 0;
while (nBytesRecv < nTotalBytes)
{
int nThisRecvSize = recv(client_sock, pszRecvData + nBytesRecv, nTotalBytes - nBytesRecv, 0);
if (nThisRecvSize < 0) // 수신 완료
{
AfxMessageBox(CString(pszRecvData));
return true;
}
nBytesRecv += nThisRecvSize;
}
}
}
else if ((NetworkEvents.lNetworkEvents & FD_CLOSE) == FD_CLOSE)
{
// 프로그램 종료 준비
WSACloseEvent(hMesgSocketEvent);
WSACleanup();
return false;
}
else
{
}
return true;
}
}
# 소스 코드 내용 ( 데이터 전송 )
int SendDataToServer()
{
CString msg = _T("hi, nice to meet you");
int nSize = msg.GetLength();
int nTotalBytes = nSize;
std::vector<char> vecTotalBytes(nTotalBytes);
char *pszSendData = &vecTotalBytes[0];
USES_CONVERSION;
memcpy(pszSendData, T2A(msg.GetString()), nTotalBytes);
int nBytesSent = 0;
while (nBytesSent < nTotalBytes)
{
int nThisSendSize = send(client_sock, pszSendData + nBytesSent, nTotalBytes - nBytesSent, 0);
if (nThisSendSize < 0)
break;
nBytesSent += nThisSendSize;
}
}
'C, C++, MFC > C, C++, MFC 테크닉' 카테고리의 다른 글
MFC 테크닉 - 파일 제어( BIN format ) (0) | 2021.12.11 |
---|---|
MFC 테크닉 - 통신 Socket ( Heartbeat - Send/Recv ) (0) | 2021.12.07 |
MFC 테크닉 - OOP (0) | 2021.11.21 |
MFC 테크닉 - 통신 CSocket (0) | 2021.11.16 |
MFC 테크닉 - 통신 Socket ( Heartbeat ) (0) | 2021.11.12 |