CClientNetwork 클래스 [Bottom] [Top]

   1 // ClientNetwork.h : CClientNetwork 클래스 선언
   2 //
   3 
   4 #pragma once
   5 
   6 
   7 // 클래스 선언
   8 class CClientNetwork
   9 {
  10         // 생성자/소멸자
  11 public:
  12         CClientNetwork();
  13         virtual ~CClientNetwork();
  14 
  15         // 멤버 함수
  16 public:
  17         void Initialize();
  18         void Cleanup();
  19 
  20         // 멤버 변수
  21 protected:
  22 
  23 };

   1 // ClientNetwork.cpp : CClientNetwork 클래스 구현
   2 //
   3 
   4 #include "StdAfx.h"
   5 #include "ClientNetwork.h"
   6 
   7 
   8 // 생성자/소멸자 구현
   9 CClientNetwork::CClientNetwork()
  10 {
  11 }
  12 
  13 CClientNetwork::~CClientNetwork()
  14 {
  15 }
  16 
  17 // 멤버 함수 구현
  18 void CClientNetwork::Initialize()
  19 {
  20         WSADATA wsaData;
  21 
  22         // WinSock2 초기화
  23         if( 0 != WSAStartup( WINSOCK_VERSION, &wsaData ) )
  24         {
  25                 printf( "error WSAStartup()" );
  26         }
  27 }
  28 
  29 void CClientNetwork::Cleanup()
  30 {
  31         // WinSock2 해제
  32         WSACleanup();
  33 }

CClientSock 클래스 [Bottom] [Top]

   1 // ClientSock.h : CClientSock 클래스 선언
   2 //
   3 
   4 #pragma once
   5 
   6 
   7 // 클래스 선언
   8 class CClientSock
   9 {
  10         // 생성자/소멸자
  11 public:
  12         CClientSock();
  13         virtual ~CClientSock();
  14 
  15         // 멤버 함수
  16 public:
  17         HRESULT Create();
  18         void Close();
  19 
  20         SOCKET GetSocket() const;
  21 
  22         // 멤버 변수
  23 protected:
  24         SOCKET m_hSock;
  25 };

   1 // ClientSock.cpp : CClientSock 클래스 구현
   2 //
   3 
   4 #include "StdAfx.h"
   5 #include "ClientSock.h"
   6 
   7 
   8 // 생성자/소멸자 구현
   9 CClientSock::CClientSock()
  10 : m_hSock( INVALID_SOCKET )
  11 {
  12 }
  13 
  14 CClientSock::~CClientSock()
  15 {
  16         Close();
  17 }
  18 
  19 // 멤버 함수 구현
  20 HRESULT CClientSock::Create()
  21 {
  22         // 소캣 생성
  23         m_hSock = WSASocket(
  24                 AF_INET,
  25                 SOCK_STREAM,
  26                 0,
  27                 NULL,
  28                 0,
  29                 WSA_FLAG_OVERLAPPED );
  30 
  31         if( INVALID_SOCKET == m_hSock )
  32         {
  33                 return E_FAIL;
  34         }
  35 
  36         return S_OK;
  37 }
  38 
  39 void CClientSock::Close()
  40 {
  41         // 소켓 닫음
  42         if( INVALID_SOCKET != m_hSock )
  43         {
  44                 closesocket( m_hSock );
  45 
  46                 m_hSock = INVALID_SOCKET;
  47         }
  48 }
  49 
  50 SOCKET CClientSock::GetSocket() const
  51 {
  52         return m_hSock;
  53 }

CClientConnector 클래스 [Bottom] [Top]

   1 // ClientConnector.h : CClientConnector 클래스 선언
   2 //
   3 
   4 #pragma once
   5 
   6 
   7 // 참조 선언
   8 class CClientSock;
   9 
  10 
  11 // 클래스 선언
  12 class CClientConnector
  13 {
  14         // 데이터형 선언
  15 public:
  16         typedef enum tagCONNECT_RESULT
  17         {
  18                 CONNECT_FAIL = -2,              // 서버 연결 실패
  19                 CONNECT_INVALID_SOCK,           // 소켓 정보 없음
  20                 CONNECT_WAIT = 0,               // 서버 연결 대기
  21                 CONNECT_OK,                     // 서버 연결 성공
  22         } CONNECT_RESULT;
  23 
  24         // 생성자/소멸자
  25 public:
  26         CClientConnector();
  27         virtual ~CClientConnector();
  28 
  29         // 멤버 함수
  30 public:
  31         HRESULT Create( CClientSock * pClientSock, char * szAddress, int nPort );
  32         void Close();
  33 
  34         CONNECT_RESULT TryConnect();
  35 
  36         HRESULT Reconnect();
  37 
  38         // 멤버 변수
  39 protected:
  40         CClientSock * m_pClientSock;
  41         SOCKADDR_IN m_serverAddr;
  42 
  43         WSAEVENT m_hConnectEvent;
  44 };

   1 // ClientConnector.cpp : CClientConnector 클래스 구현
   2 //
   3 
   4 #include "StdAfx.h"
   5 #include "ClientConnector.h"
   6 #include "ClientSock.h"
   7 
   8 
   9 // 생성자/소멸자 구현
  10 CClientConnector::CClientConnector()
  11 : m_pClientSock( NULL )
  12 , m_hConnectEvent( NULL )
  13 {
  14 }
  15 
  16 CClientConnector::~CClientConnector()
  17 {
  18         Close();
  19 }
  20 
  21 // 멤버 함수 구현
  22 HRESULT CClientConnector::Create( CClientSock * pClientSock, char * szAddress, int nPort )
  23 {
  24         // 소켓 객체 체크
  25         if( NULL == pClientSock )
  26         {
  27                 return E_FAIL;
  28         }
  29 
  30         m_pClientSock = pClientSock;
  31 
  32         // 서버 주소 설정
  33         memset( &m_serverAddr, 0, sizeof( m_serverAddr ) );
  34         m_serverAddr.sin_family = AF_INET;
  35         m_serverAddr.sin_addr.s_addr = inet_addr( szAddress );
  36         m_serverAddr.sin_port = htons( nPort );
  37 
  38         // 소켓 Event 객체 생성
  39         m_hConnectEvent = WSACreateEvent();
  40 
  41         if( WSA_INVALID_EVENT == m_hConnectEvent )
  42         {
  43                 return E_FAIL;
  44         }
  45 
  46         // 소켓 Event 객체 설정
  47         int nResult = WSAEventSelect(
  48                 m_pClientSock->GetSocket(),
  49                 m_hConnectEvent,
  50                 FD_CONNECT );
  51 
  52         if( SOCKET_ERROR == nResult )
  53         {
  54                 return E_FAIL;
  55         }
  56 
  57         // 비동기 연결 시도
  58         return Reconnect();
  59 }
  60 
  61 void CClientConnector::Close()
  62 {
  63         // 소켓 Event 객체 삭제
  64         if( NULL != m_hConnectEvent )
  65         {
  66                 WSACloseEvent( m_hConnectEvent );
  67         }
  68 }
  69 
  70 CClientConnector::CONNECT_RESULT CClientConnector::TryConnect()
  71 {
  72         // 소켓 객체 체크
  73         if( NULL == m_pClientSock )
  74         {
  75                 return CONNECT_INVALID_SOCK;
  76         }
  77 
  78         // 소켓 Event 객체 체크
  79         DWORD dwResult = WSAWaitForMultipleEvents( 1, &m_hConnectEvent, FALSE, 0, FALSE );
  80 
  81         if( dwResult == WSA_WAIT_EVENT_0 )
  82         {
  83                 WSANETWORKEVENTS networkEvents;
  84 
  85                 int nResult = WSAEnumNetworkEvents(
  86                         m_pClientSock->GetSocket(),
  87                         m_hConnectEvent,
  88                         &networkEvents );
  89 
  90                 // 소켓 Event 객체 에러 체크
  91                 return ( ( 0 != networkEvents.iErrorCode[FD_CONNECT_BIT] ) ? CONNECT_FAIL : CONNECT_OK );
  92         }
  93 
  94         return CONNECT_WAIT;
  95 }
  96 
  97 HRESULT CClientConnector::Reconnect()
  98 {
  99         // 비동기 연결 시도
 100         if( SOCKET_ERROR == connect(
 101                 m_pClientSock->GetSocket(),
 102                 reinterpret_cast< sockaddr * >( &m_serverAddr ),
 103                 sizeof( m_serverAddr ) ) )
 104         {
 105                 if( WSAEWOULDBLOCK != WSAGetLastError() )
 106                 {
 107                         return E_FAIL;
 108                 }
 109         }
 110 
 111         return S_OK;
 112 }

비동기 Connect 예제 [Bottom] [Top]

   1 // stdafx.h : 미리 컴파일된 헤더
   2 //
   3 
   4 #pragma once
   5 
   6 
   7 #define WIN32_LEAN_AND_MEAN
   8 #include <stdio.h>
   9 #include <stdlib.h>
  10 
  11 #include <windows.h>
  12 #include <winsock2.h>
  13 
  14 #pragma comment(lib, "ws2_32.lib")

   1 // Main.cpp : 비동기 연결 예제
   2 //
   3 
   4 #include "stdafx.h"
   5 #include "ClientNetwork.h"
   6 #include "ClientSock.h"
   7 #include "ClientConnector.h"
   8 
   9 
  10 int main( int argc, char * argv[] )
  11 {
  12         if( 3 != argc )
  13         {
  14                 printf( "Usage: %s <IP> <PORT>\n", argv[0] );
  15 
  16                 exit( 1 );
  17         }
  18         else
  19         {
  20                 CClientNetwork clientNetwork;
  21                 CClientSock clientSock;
  22                 CClientConnector connector;
  23 
  24                 // STEP 1: WinSock2 초기화
  25                 clientNetwork.Initialize();
  26 
  27                 // STEP 2: 소켓 생성
  28                 clientSock.Create();
  29 
  30                 // SETP 3: 비동기 연결 시도
  31                 connector.Create( &clientSock, argv[1], atoi( argv[2] ) );
  32 
  33                 int nCount = 10;
  34 
  35                 do {
  36                         // STEP 4: 연결 체크
  37                         int nResult = connector.TryConnect();
  38 
  39                         while( CClientConnector::CONNECT_WAIT == nResult )
  40                         {
  41                                 // STEP 4-1: 연결 체크
  42                                 nResult = connector.TryConnect();
  43 
  44                                 // STEP 4-2: 반환값 처리
  45                                 switch( nResult )
  46                                 {
  47                                 case CClientConnector::CONNECT_FAIL:
  48                                         printf( "연결 실패!\n" );
  49                                         break;
  50 
  51                                 case CClientConnector::CONNECT_INVALID_SOCK:
  52                                         printf( "소켓 에러!\n" );
  53                                         break;
  54 
  55                                 case CClientConnector::CONNECT_WAIT:
  56                                         printf( "연결 대기...\n" );
  57                                         break;
  58 
  59                                 case CClientConnector::CONNECT_OK:
  60                                         printf( "연결 성공!\n" );
  61                                         break;
  62                                 }
  63 
  64                                 Sleep( 200 );
  65                         }
  66 
  67                         if( CClientConnector::CONNECT_OK == nResult )
  68                         {
  69                                 break;
  70                         }
  71 
  72                         // STEP 5: 재연결 시도
  73                         connector.Reconnect();
  74 
  75                 } while( --nCount );
  76 
  77                 // STEP 6: WinSock2 해제
  78                 clientNetwork.Cleanup();
  79         }
  80 
  81         return 0;
  82 }


CategoryNetwork

비동기 Connect 처리하기 (last edited 2006-08-25 07:35:30 by viper)