AsyncSocket 클래스 – 소켓당 스레드 버젼 (ver 0.01)


1 소개 #

간만의 연휴를 이용해서 비동기 소켓클래스를 만들어 봤다… 잘 되는지는 별로 태스를 안해봐서 모르겠다. 음 비동기 모드로 만들때 WSAEventSelect 를 이용해서 비동기 모드로 전화시키고 각 소켓과 WSAEvent를 맵핑한뒤 스래드에서 WaitForMultipleObject 를 이용해서 발생한 이벤트를 얻고 해당소켓을 찾아 어떤 소켓이벤트가 발생했는지 판단해 해당 이벤트 함수를 호출하는 형식인데 문제는 WaitForMultipleObject 의 인자중 이벤트배열을 집어넣는것이 한번에 64개 밖에는 안된다는 것! 이 문제로 인해 스레드당 처리할수 있는 소켓의 개수는 최대 64개(스레드 종료 이벤트 등을 생각하면 60개정도) 밖에 되지 않는다는것.. 서버로 사용될경우 처리할 소켓이 늘어나면 스래드를 늘려줘야 한다는 단점이 있다. 아직 위의 스레드 관리에 관한건 생각해보지 않아서 소켓당 스레드 하나의 버젼으로 간단히 만들었다.(스레드 관리뿐 아니라 스레드 마다의 소켓을 관리하는것도) 나중에 꼭 수정을 하리라!


2 Code #


#ifndef _ASYNC_CONNECTOR_
#define _ASYNC_CONNECTOR_

#include <iostream.h>
#include <winsock2.h>

class CAsyncConnector
{
public:
CAsyncConnector();
virtual ~CAsyncConnector();

// 소켓초기화 및 종료화 함수 // 뽀대나게 스태틱으로
static int Cleanup();
static int Startup();

// 소켓초기화 함수 : 언제나 TCP 비동기소켓을 생성한다.
SOCKET InitializeSocket();
// 소켓을 닫는 함수
int CloseSocket();

// 소켓 연결함수
int ConnectToIP(LPCSTR lpcIP, UINT uPort);
int ConnectToDomain(LPCSTR lpcDomain, UINT uPort);

// send, recv API 함수
int Receive(byte* pDataBuf, int nBufSize);
int Send(byte* pSendData, int nDataSize);

// bind, listen API 함수 :: 서버만 사용
int Binding(UINT uPort);

// 클래스 맴버변수를 얻는 함수
WSAEVENT* GetEvenHandle();
SOCKET GetSocket();

// domain 으로 부터 IP를 얻는 함수
BOOL GetIPfromDomain(LPCSTR lpcDomain);

// 소켓이벤트 처리 스레드
HANDLE StartThreadEventSelect();
int StopThreadEventSelect();
static DWORD WINAPI EventSelectThread(LPVOID lpArg);

private:
// 클래스 인스턴스의 개수
static int m_nCountInstance;

// 이 연결자가 사용하는 소켓
SOCKET m_Socket;
sockaddr_in m_SockAddr;

// 소켓 이벤트핸들 0=소켓이벤트 1=스레드증료
WSAEVENT m_hEvent[2];

// EventSelect 스레드를 관리하는 변수
HANDLE m_hEventSelectThreadHandle;
DWORD m_dwEventSelectThreadId;

protected:
// 오버라이딩용 함수들
virtual void OnReceive(int nErrorCode);
virtual void OnSend(int nErrorCode);
virtual void OnOutOfBandData(int nErrorCode);
virtual void OnAccept(int nErrorCode);
virtual void OnConnect(int nErrorCode);
virtual void OnClose(int nErrorCode);
};

#endif



3 소스 #

비주얼스튜디오 6.0에서 작업

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다