반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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
Archives
Today
Total
관리 메뉴

폴크(FOLC)

MFC 테크닉 - 통신 WinSock ( Client ) 본문

C, C++, MFC/C, C++, MFC 테크닉

MFC 테크닉 - 통신 WinSock ( Client )

folcjin 2021. 11. 23. 22:57
728x90
반응형

# 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;
   }
}

728x90
반응형
사업자 정보 표시
사업자 등록번호 : -- | TEL : --