// IOCP.cpp
#define WIN32_LEAN_AND_MEAN //
Exclude rarely-used stuff from Windows headers
#include <<span class=SpellE>windows.h>
#include
#include <<span class=SpellE>stdio.h>
#define MY_RECV_BUFFER 512
//#define MY_CHAT_PORT 50000
#define MY_MAX_CLIENT 10
#define MY_MAX_PACKET 100
class CClient
{
public:
enum MODE { PACKET_BODY, PACKET_LENGTH };
SOCKET
m_Socket;
int m_nPI;
int m_nRI;
short
m_nPacketLen;
MODE
m_eMode;
public:
CClient()
{
m_Socket = INVALID_SOCKET;
m_nPI = m_nRI = 0;
m_nPacketLen = 0;
m_eMode = PACKET_BODY;
}
};
#define READ 1
#define WRITE 2
class CXOverlapped
: public OVERLAPPED
{
public:
int mode; //
Read냐 Write냐..결정.
char
szRecv[MY_RECV_BUFFER];
int iNum; //
Send할 때, 같은 데이터를 여러 개 만들지
// 않기 위해서 사용하는 변수이다.
// 원리는 이 구조체를 사용하여 Send를 하면
// iNum값을 1씩 증가
시킨다. 작업 완료 처리
// 루틴에서 Send가 완료 되었으면 이 값을 1씩
// 빼주고 0이 된 구조체를 delete한다.
CXOverlapped()
{
Clear();
mode
= READ;
}
~CXOverlapped()
{
}
inline
void Clear()
{
Internal
= 0;
InternalHigh = 0;
Offset
= 0;
OffsetHigh = 0;
hEvent = 0;
}
};
SOCKET g_sockListen; //클라이언트의 접속을 대기하는 소켓
int g_nClients = 0; //현재
몇명의 클라이언트가 접속했는지 저장.
CClient g_ClientsC[MY_MAX_CLIENT];
HANDLE g_hCompletionPort;
// 소켓 초기화 함수.
BOOL InitSocket()
{
WORD
wVer;
WSADATA
wsaData;
SOCKADDR_IN
serv_addr;
wVer = MAKEWORD(1,1);
if(WSAStartup(wVer, &wsaData) != 0)
{
printf( "WSAStartup() 실패 :
%d\\n", WSAGetLastError());
return
FALSE;
}
g_sockListen = socket(AF_INET, SOCK_STREAM, 0);
if
( g_sockListen == INVALID_SOCKET )
{
printf( "socket() 실패 : %d\\n", WSAGetLastError());
return
FALSE;
}
ZeroMemory (&serv_addr, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(MY_CHAT_PORT);
if(
bind( g_sockListen, (LPSOCKADDR)&serv_addr, sizeof(serv_addr) ) ==
SOCKET_ERROR )
{
printf( "bind() 실패 : %d\\n", WSAGetLastError());
return
FALSE;
}
if
(listen(g_sockListen, 5) == SOCKET_ERROR)
{
printf( "listen() 실패 : %d\\n", WSAGetLastError());
return
FALSE;
}
printf("g_sockListen 소켓 초기화
성공\\n");
return
TRUE;
}
void PacketProcess(
char* pPacket )
{
//
여기서 패킷에 대한 처리를 하며 된다.
}
DWORD WINAPI WorkerThread(
void* pModel )
{
DWORD
dwBytesTransferred;
DWORD
dwCompKey;
CXOverlapped* pPacket;
LPOVERLAPPED
pOverlap;
printf( "Worker 시작\\n" );
while(
1 )
{
//////////////////////////////////////////
//3.
Read Request from client
//////////////////////////////////////////
if(
FALSE == GetQueuedCompletionStatus( g_hCompletionPort, &dwBytesTransferred,
&dwCompKey, (LPOVERLAPPED *)&pOverlap,
INFINITE ) )
{
if(
pOverlap != NULL )
{
printf( "Error Thread : GetQueueCompletionStatus(
%d )\\n",
GetLastError() );
return
0;
}
}
if(
dwBytesTransferred == 0 )
{
printf("Closing socket %d\\n", g_ClientsC[dwCompKey] );
if(
SOCKET_ERROR == closesocket( g_ClientsC[dwCompKey].m_Socket ) )
{
if(GetLastError() == 10038 |