www.pudn.com > back.rar > iocpnet.cpp
//IOCPNet.cpp
#include "stdafx.h"
#include "IOCPNet.h"
/*
worker threads
*/
CIOCPNet g_IOCPNet;
::ofstream g_closenumber;
DWORD WINAPI _xThread(LPVOID pVoid)
{
CIOCPNet* pIOCPNet = (CIOCPNet*)pVoid;
pIOCPNet->Process();
return 1;
}
DWORD WINAPI _xListenThread(LPVOID pVoid)
{
CIOCPNet* pIOCPNet = (CIOCPNet*)pVoid;
pIOCPNet->Accept();
return 1;
}
/*
CIOCPNet member functions
*/
CIOCPNet::CIOCPNet()
{
int i = 0;
for (i = 0 ; i < IOCP_THREADS_PER_CPU ; i ++) m_hThreads[i] = NULL;
m_hIOCP = INVALID_HANDLE_VALUE;
for ( i = 0 ; i < SOCKET_MAX_LISTEN ; i++) m_ListenSoc[i] = INVALID_SOCKET;
InitializeCriticalSection(&m_ListenFlag);
InitializeCriticalSection(&m_ListenFlag_Server);
for ( i = 0 ; i < IOCP_MAX_CLIENT_ACCPET ; i++)
g_ClientArray[i].SetClientNumber(i);
m_pMultiToken = NULL;
m_bPause = TRUE;
m_bOperate = TRUE;
m_dwCurrentTime = 0;
m_IOCPclosenumber.open( "IOCPclosenumber" );
//set client 0 for multi server
m_iClients++;
}
CIOCPNet::~CIOCPNet()
{
m_IOCPclosenumber.close();
DeleteCriticalSection(&m_ListenFlag);
DeleteCriticalSection(&m_ListenFlag_Server);
}
void CIOCPNet::GetLocalName(char* addr)
{
if (addr == NULL) return;
char name[255];
char* address;
PHOSTENT hostinfo;
if( gethostname ( name, sizeof(name)) == 0)
{
if((hostinfo = gethostbyname(name)) != NULL)
{
address = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
}
else return;
}
else return;
strcpy(addr,address);
}
bool CIOCPNet::Init(HWND hParents, CIOCPToken* pToken, CMultiToken* pMultiToken)
{
//¿©±â¼ ¿°í
g_closenumber.open("closenumber.txt");
if (pToken == NULL) return false;
m_pToken = pToken;
m_pMultiToken = pMultiToken;
//Get system info
GetSystemInfo(&m_SysInfo);
//create completion port ( cpu * IOCP_THREADS_PER_CPU ) ¾²·¡µå¼ö »ý¼º
if ((m_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0)) == NULL)
return false;
//create threads
HANDLE hThread;
DWORD dwThreadId;
for(DWORD dwi = 0; dwi m_nListenSocketCount + iPlus || i < m_pMultiToken->GetTotalServerCount(); i++)
{
if( m_pMultiToken->m_SocInfo[i].bListen == false )
iPlus++;
else
if (!InitListen(m_pMultiToken->m_SocInfo[i].nPort,(WORD)i,m_pMultiToken->m_SocInfo[i].szIP)) return FALSE; //listen fail
}
m_pMultiToken->Connect(this);
}
m_bPause = FALSE;
//Resume accept thread.
ResumeThread(m_hThreadAccept);
return true;
}
BOOL CIOCPNet::InitListen(long port,WORD wlisten,char* LocalIP)
{
WSADATA wsaData;
SOCKADDR_IN serv_addr;
WORD wVer = MAKEWORD(2,0);
if(WSAStartup(wVer, &wsaData) != 0) return FALSE;
m_ListenSoc[wlisten] = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
if ( m_ListenSoc[wlisten] == INVALID_SOCKET ) return FALSE;
if (LocalIP == NULL)
{
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons((unsigned short)port);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
}
else
{
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons((unsigned short)port);
serv_addr.sin_addr.s_addr = inet_addr(LocalIP);
}
BOOL bRe = TRUE;
setsockopt(m_ListenSoc[wlisten], SOL_SOCKET, SO_REUSEADDR, (char*) &bRe, sizeof(BOOL));
if (bind (m_ListenSoc[wlisten], (LPSOCKADDR)&serv_addr, sizeof(serv_addr))== SOCKET_ERROR)
{
// int k = WSAGetLastError();
return FALSE;
}
BOOL opt = TRUE;
if(SOCKET_ERROR == setsockopt(m_ListenSoc[wlisten], IPPROTO_TCP, TCP_NODELAY , (char*) &opt, sizeof(int)))
return FALSE;
LINGER LingerStruct;
LingerStruct.l_onoff = 1;
LingerStruct.l_linger = 0;
int nZero = 0;
opt = TRUE;
if(SOCKET_ERROR == setsockopt(m_ListenSoc[wlisten], SOL_SOCKET, SO_LINGER,(char*) &opt, sizeof(LingerStruct)))
return FALSE;
if (listen (m_ListenSoc[wlisten] , SOMAXCONN ) == SOCKET_ERROR)
return FALSE;
return TRUE;
}
/*
BOOL CIOCPNet::Accept()
*/
BOOL CIOCPNet::Accept()
{
timeval TimeVal;
fd_set Temp_set;
TimeVal.tv_sec = 0;
TimeVal.tv_usec = 1;
if (m_pMultiToken == NULL) return 1;
while (m_bOperate)
{
int iPlus = 0;
for (int i = 0 ; i < m_pMultiToken->m_nListenSocketCount + iPlus || i < m_pMultiToken->GetTotalServerCount() ; i++)
{
if( m_pMultiToken->m_SocInfo[i].bListen == false )
iPlus++;
else
{
if (m_ListenSoc[i] == INVALID_SOCKET) continue;
FD_ZERO (&Temp_set);
FD_SET (m_ListenSoc[i] , &Temp_set);
select(IOCP_MAX_CLIENT_ACCPET, &Temp_set, NULL, NULL, &TimeVal);
if (FD_ISSET (m_ListenSoc[i], &Temp_set))
{
Accept( m_ListenSoc[i],i,m_pMultiToken->m_SocInfo[i].nRecvSockBuffer,
m_pMultiToken->m_SocInfo[i].nSendSockBuffer,
m_pMultiToken->m_SocInfo[i].nReadQueueBuffer,
m_pMultiToken->m_SocInfo[i].nSendQueueBuffer);
}
}
}
Sleep(1);
}
return 1;
}
/*
BOOL CIOCPNet::Accept(SOCKET socket)
*/
BOOL CIOCPNet::SockOptionSet(SOCKET soc,int nNum,int nRecvSockBuffer,int nSendSockBuffer)
{
//set options
if(SOCKET_ERROR == setsockopt(soc, SOL_SOCKET, SO_SNDBUF, (char*) &nSendSockBuffer, sizeof(nSendSockBuffer)))
{
return FALSE;
}
if(SOCKET_ERROR == setsockopt(soc, SOL_SOCKET, SO_RCVBUF, (char*) &nRecvSockBuffer, sizeof(nRecvSockBuffer)))
{
return FALSE;
}
int nZero = 0;
BOOL opt = TRUE;
//Nagle off
if(SOCKET_ERROR == setsockopt(soc, IPPROTO_TCP, TCP_NODELAY , (char*) &opt, sizeof(nZero)))
return FALSE;
//linger option off
LINGER LingerStruct;
LingerStruct.l_onoff = 1;
LingerStruct.l_linger = 0;
nZero = 0;
opt = TRUE;
if(SOCKET_ERROR == setsockopt(soc, SOL_SOCKET, SO_LINGER,(char*) &opt, sizeof(LingerStruct)))
return FALSE;
return TRUE;
}
int CIOCPNet::GetEmptyClient()
{
DWORD dwCooltime = GetTickCount();
for (int i = BRAVO_MAX_MULTI_SERVER ; i < IOCP_MAX_CLIENT_ACCPET ; i ++)
{//find empty client! kkkk
if (!g_ClientArray[i].IsConnected() && (g_ClientArray[i].m_dwCoolTime < dwCooltime))
{
return i;
}
}
return -1;
}
BOOL CIOCPNet::Accept(SOCKET listen,int nNum,int nRecvSockBuffer,int nSendSockBuffer,
int nReadQueueBuffer,int nSendQueueBuffer)
{
if(m_hIOCP == NULL) return FALSE;
//if (nNum != 0 && g_ClientArray[nNum].IsConnected()) // »ì¾Æ Àִµ¥? Áߺ¹ ¼¹ö Á¢¼Ó??
//{
// g_ClientArray[nNum].Close( 2000 );
//}
SOCKADDR_IN cli_addr;
int cli_len;
cli_len = sizeof(cli_addr);
//accept socket
SOCKET socIncoming;
socIncoming = accept(listen, (LPSOCKADDR)&cli_addr, &cli_len);
char ClientIP[25];
memset(ClientIP,0x00,sizeof(char)*25);
sprintf(ClientIP,"%d.%d.%d.%d",(int)(cli_addr.sin_addr.S_un.S_un_b.s_b1),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b2),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b3),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b4));
if (nNum != 0 && g_ClientArray[nNum].IsConnected()) // »ì¾Æ Àִµ¥? Áߺ¹ ¼¹ö Á¢¼Ó??
{
if( strcmp( m_pMultiToken->m_SocInfo[nNum].szLocalIP , ClientIP ) != 0 )//ÇöÀç ºÙÀ» ¼¹ö¶û ºÙ°íÀÚ ÇÏ´Â ¼¹ö°¡ ´Ù¸£¸é ¸®ÅÏ
{
//MessageBox(NULL,m_pMultiToken->m_SocInfo[nNum].szLocalIP,"txt",MB_OK);
//MessageBox(NULL,ClientIP,"Clientip",MB_OK);
shutdown(socIncoming,SD_BOTH );
closesocket(socIncoming);
return false;
}
//MessageBox(NULL,m_pMultiToken->m_SocInfo[nNum].szLocalIP,"txt",MB_OK);
//MessageBox(NULL,ClientIP,"Clientip",MB_OK);
shutdown(socIncoming,SD_BOTH );
closesocket(socIncoming);
g_ClientArray[nNum].Close( 2000 );
}
if (socIncoming == INVALID_SOCKET) return FALSE;
if (!SockOptionSet(socIncoming,0,nRecvSockBuffer,nSendSockBuffer))
{
shutdown(socIncoming,SD_BOTH );
closesocket(socIncoming);
return FALSE;
}
HANDLE hResult = NULL;
// Client ¹øÈ£¸¦ ¹Þ°í ..À̰ÍÀú°Í ¼¼ÆÃ.
if (nNum == 0 )
{//client
EnterCriticalListen();
int i = GetEmptyClient();
if (i < 0){LeaveCriticalListen();closesocket(socIncoming);return FALSE;}
g_ClientArray[i].Init(nReadQueueBuffer,nSendQueueBuffer);
g_ClientArray[i].SetSocket(socIncoming);
g_ClientArray[i].SetClientNumber(i);
g_ClientArray[i].SetConnectFlag(TRUE);
sprintf(g_ClientArray[i].m_szPeerName,"%d.%d.%d.%d",(int)(cli_addr.sin_addr.S_un.S_un_b.s_b1),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b2),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b3),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b4));
m_iClients++;
hResult = CreateIoCompletionPort((HANDLE)g_ClientArray[i].GetSocket(), m_hIOCP, i, 0);
LeaveCriticalListen();
m_pToken->Connected(i);
g_ClientArray[i].Read();
}
else
{//server
EnterCriticalSListen();
g_ClientArray[nNum].Init(nReadQueueBuffer,nSendQueueBuffer);
g_ClientArray[nNum].SetSocket(socIncoming);
g_ClientArray[nNum].SetClientNumber(nNum);
g_ClientArray[nNum].SetConnectFlag(TRUE);
sprintf(g_ClientArray[nNum].m_szPeerName,"%d.%d.%d.%d",(int)(cli_addr.sin_addr.S_un.S_un_b.s_b1),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b2),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b3),
(int)(cli_addr.sin_addr.S_un.S_un_b.s_b4));
m_iClients++;
hResult = CreateIoCompletionPort((HANDLE)g_ClientArray[nNum].GetSocket(), m_hIOCP, nNum, 0);
LeaveCriticalSListen();
if (m_pMultiToken != NULL) m_pMultiToken->Connected(nNum,nNum); // ´ÙÀ̾˷α׿¡ »óŸ¦ ¾Ë¸²
g_ClientArray[nNum].Read();
}
#ifdef IOCP_DEBUG
char connectstr[128];
sprintf(connectstr,"%d client connected from %d listen socket \n",nNum,nNum);
//* OutputDebugString(connectstr);
#endif
return TRUE;
}
void CIOCPNet::CloseClient(int iClient)
{
if (iClient < BRAVO_MAX_MULTI_SERVER)
EnterCriticalSListen();
else
EnterCriticalListen();
if (g_ClientArray[iClient].IsConnected() == TRUE)
{
g_ClientArray[iClient].m_dwCoolTime = GetTickCount() + CLIENT_COOL_TIME;
#ifdef IOCP_DEBUG
char closeinfo[128];
sprintf(closeinfo,"%d client closed\n",iClient);
//* OutputDebugString(closeinfo);
#endif
CancelIo((HANDLE)g_ClientArray[iClient].GetSocket());
shutdown(g_ClientArray[iClient].GetSocket(),SD_RECEIVE);
closesocket(g_ClientArray[iClient].GetSocket());
g_ClientArray[iClient].SetConnectFlag(FALSE);
if (iClient < BRAVO_MAX_MULTI_SERVER) //server
{
if (m_pMultiToken != NULL)
{
m_iClients--;
g_ClientArray[iClient].m_dwLastReceviedCount = 0;
g_ClientArray[iClient].m_dwLastReceivedTime = 0;
LeaveCriticalSListen();
m_pMultiToken->DisConnect(iClient);
return;
}
}
else
{
m_iClients--;
g_ClientArray[iClient].m_dwLastReceviedCount = 0;
g_ClientArray[iClient].m_dwLastReceivedTime = 0;
LeaveCriticalListen();
m_pToken->DisConnected(iClient);
return;
}
}
else
{
#ifdef IOCP_DEBUG
char closeinfo[128];
sprintf(closeinfo,"%d client closed second time\n",iClient);
//* OutputDebugString(closeinfo);
#endif
}
if (iClient < BRAVO_MAX_MULTI_SERVER)
LeaveCriticalSListen();
else
LeaveCriticalListen();
}
/*
BOOL CIOCPNet::Process()
process read and write process
work in background
*/
BOOL CIOCPNet::Process()
{
BOOL bResult = FALSE;
DWORD dwCompKey;
LPOVERLAPPED lpOverlapped = NULL;
DWORD dwTransferred = 0;
OVERLAPPED_BASE* lpOverlappedBase = NULL;
int temcount = 0;
while(m_bOperate)
{
bResult = GetQueuedCompletionStatus(
m_hIOCP,
&dwTransferred,
&dwCompKey,
&lpOverlapped,
INFINITE
);
if (bResult == 0)
{
//clientÁ¾·áó¸®
m_IOCPclosenumber << "10" << "\n";
CloseClient((int)dwCompKey);
continue;
}
lpOverlappedBase = (OVERLAPPED_BASE*)lpOverlapped;
if (dwTransferred == SOCKET_ERROR)
{//socket ¿¡·¯Àϰæ¿ì
if( GetLastError() != ERROR_IO_PENDING )
{//error io pending ÀÌ ¾Æ´Ï¸é Ä¡¸íÀû ¿¡·¯
// linger ¿É¼Ç Ű°í ²÷´Â´Ù..
m_IOCPclosenumber << "11" << "\n";
CloseClient((int)lpOverlappedBase->m_iClient);
}
continue;
}
//0¹ÙÀÌÆ® ¼º°øÀÏ °æ¿ì´Â ¼ÒÄÏÀÌ ²÷¾îÁø °æ¿ì
if (dwTransferred == 0)
{
m_IOCPclosenumber << "12" << "\n";
CloseClient((int)lpOverlappedBase->m_iClient);
continue;
}
switch (lpOverlappedBase->m_sEvent)
{
case IOCP_EVENT_READ:
{
//ÀоúÀ½
//¸Þ¼¼Áö ºÐÇÒó¸®
AnalyizeMsg((int)lpOverlappedBase->m_iClient,dwTransferred);
}
break;
case IOCP_EVENT_WRITE:
{
g_ClientArray[lpOverlappedBase->m_iClient].WriteFinish(dwTransferred);
}
break;
default :
m_IOCPclosenumber << "13" << "\n";
CloseClient((int)dwCompKey);
break;
}
}
return TRUE;
}
DWORD CIOCPNet::GetMsgSize(_header Header,UINT iClient)
{
if (Header.wID[0] < IOCP_MAX_CLIENT_MESSAGES)
{
if (Header.wID[1] >= BRAVO_ZONEMSG_KEY) //msg from zoneserver
return g_arydwMsgSize_fromClient[Header.wID[0]];
else
return g_arydwMsgSize[Header.wID[0]];
}
else
{
#ifdef IOCP_DEBUG
char log[128];
sprintf(log,"%d client sent message is exceeded the header number(%d)\n",iClient,(int)Header.wID[0]);
//* OutputDebugString(log);
#endif
return 0;
}
return 0;
}
/*
void CIOCPNet::AnalyizeMsg(UINT iClient,DWORD dwSize)
¹ÞÀº ¹öÆÛÀÇ ³»¿ëÀ» ºÐ¼®ÇÏ¿© µµÂøÇÑ ¸Þ¼¼Áö´Â Readqueue ¿¡ ³Ö¾îÁØ´Ù
*/
void CIOCPNet::AnalyizeMsg(UINT iClient,DWORD dwSize)
{
// g_ClientArray[iClient].EnterWriteCS();
CXClient* pClient = (CXClient*)&(g_ClientArray[iClient]);
//even headers not arrived. return
pClient->m_XReceiveBuffer->m_dwSize += dwSize;
if (pClient->m_XReceiveBuffer->m_dwSize < sizeof(SIOCPPacket))
{
// g_ClientArray[iClient].LeaveWriteCS();
return;
}
DWORD dwTempBufferPos = 0; //used for multiful reeceived message
_header Header = *((_header*)(pClient->m_XReceiveBuffer->m_szBuffer));
DWORD MsgSize = 0;
// Çì´õ º¹È£È
#ifdef CRYPT
if( iClient >= BRAVO_MAX_MULTI_SERVER )
{
g_Crypt.Decrypt( &Header, sizeof( _header ) );
}
#endif
MsgSize = GetMsgSize(Header, iClient);
if (MsgSize == 0)
{//undefined message
// g_ClientArray[iClient].LeaveWriteCS();
pClient->Close(10000);return ;
}
//////////////////////////////////////////////////////////////////////////
// speed hack!!!!
m_IOCPclosenumber << "ÊÕµ½ " << iClient << " µÄ°ü " << Header.wID[0] << " ʱ¼ä " << g_dwCurTickTime << "\n";
m_IOCPclosenumber.flush();
//////////////////////////////////////////////////////////////////////////
int Rcount = 0;
while ( pClient->m_XReceiveBuffer->m_dwSize >= MsgSize )
{//defined message arrived
// º¹È£È...¾ÏȣȰü·Ã 6-20
#ifdef CRYPT
if( iClient >= BRAVO_MAX_MULTI_SERVER )
{
g_Crypt.Decrypt( pClient->m_XReceiveBuffer->m_szBuffer + dwTempBufferPos, MsgSize );
}
#endif
if (!g_XReadQueue.InQueue(//message buffer
pClient->m_XReceiveBuffer->m_szBuffer + dwTempBufferPos,
MsgSize, //this message size
iClient, //client number
0,
TRUE
))
{
// in case of buffer overqueue errors
// g_ClientArray[iClient].LeaveWriteCS();
pClient->Close(20000);
return;
}
//prepare for next message
dwTempBufferPos += MsgSize; //current client buffer pos
pClient->m_XReceiveBuffer->m_dwSize -= MsgSize; //current client buffer size
if (pClient->m_XReceiveBuffer->m_dwSize < sizeof(SIOCPPacket)) break;
_header Header = *((_header*)(pClient->m_XReceiveBuffer->m_szBuffer + dwTempBufferPos));
#ifdef CRYPT
if( iClient >= BRAVO_MAX_MULTI_SERVER )
{
g_Crypt.Decrypt( &Header, sizeof( _header ) );
}
#endif
MsgSize = GetMsgSize(Header,iClient);
if (MsgSize == 0)
{//undefined message
// g_ClientArray[iClient].LeaveWriteCS();
pClient->Close(30000);return ;
}
Rcount++;
}//end of while
//if unfinished data remains in client buffer
if (pClient->m_XReceiveBuffer->m_dwSize > 0)
{
memcpy(pClient->m_XReceiveBuffer->m_szBuffer,
pClient->m_XReceiveBuffer->m_szBuffer + dwTempBufferPos,
pClient->m_XReceiveBuffer->m_dwSize);
}
// g_ClientArray[iClient].LeaveWriteCS();
pClient->Read();
}
void CIOCPNet::Stop()
{
m_bOperate = FALSE;
if (m_pMultiToken != NULL) m_pMultiToken->Stop(); //Stop the Token
DWORD dwExitCode = 6;
TerminateThread(m_hThreadAccept,dwExitCode); //Stop accept thread
if (m_pMultiToken != NULL) m_pMultiToken->Stop(); //Stop the Token
for (int i = 0 ; i < IOCP_THREADS_PER_CPU ; i++)
{
dwExitCode = 10+i;
TerminateThread( m_hThreads[i], dwExitCode); // exit code for the thread
}
//¿©±â¼ ´Ý°í
g_closenumber.close();
}
/*
Connect(char* szPeerName, long port, int nClient)
óÀ½ÀÏ °æ¿ì¿¡´Â nClient == IOCP_MAX_CLIENT_ACCPET -1
Áß°£¿¡ ²÷¾îÁ³À»°æ¿ì¿¡´Â client ¹øÈ£¸¦ »õ·Î ¹ÞÁö¾Ê°í ±× ¹øÈ£·Î °Á
*/
int CIOCPNet::Connect(char* szPeerName, long port, int nClient,char* szLocalIP,int SocReadBuffer,int SocWriteBuffer
,int ReadQueueBuffer,int SendQueueBuffer)
{
EnterCriticalSListen();
UINT i;
SOCKADDR_IN sockaddr;
sockaddr.sin_port = htons((unsigned short)port);
DWORD dwPeerAddress = inet_addr(szPeerName);
sockaddr.sin_addr.s_addr = inet_addr(szPeerName);//dwPeerAddress;
sockaddr.sin_family = AF_INET;
i = nClient;
SOCKET tempsocket= socket(AF_INET, SOCK_STREAM, 0);
if (tempsocket == INVALID_SOCKET)
{
LeaveCriticalSListen();
return -1;
}
if (!SockOptionSet(tempsocket,0,SocReadBuffer,SocWriteBuffer)) return -1;
if (szLocalIP != NULL)
{
SOCKADDR_IN local_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_port = 0; /// kernel chooses port
local_addr.sin_addr.s_addr = inet_addr( szLocalIP ); /// local address bind
if( bind( tempsocket, (struct sockaddr *)&local_addr, sizeof(local_addr) ) == SOCKET_ERROR )
{
closesocket(tempsocket);
LeaveCriticalSListen();
return -1;
}
}
if (0 != connect(tempsocket, (SOCKADDR *)&sockaddr, sizeof (SOCKADDR_IN)))
{
closesocket(tempsocket);
LeaveCriticalSListen();
return -1;
}
g_ClientArray[nClient].Init(ReadQueueBuffer,SendQueueBuffer); // m_XReceiveBuffer.m_dwSize = 0; m_Socket = INVALID_SOCKET; ·Î ¼ÂÆÃ
g_ClientArray[nClient].SetSocket(tempsocket); //m_SocketÀ» ¼ÂÆÃÇÑ´Ù.
g_ClientArray[nClient].SetClientNumber(i);
HANDLE hResult = NULL;
hResult = CreateIoCompletionPort((HANDLE)g_ClientArray[nClient].GetSocket(), m_hIOCP, nClient, 0);
g_ClientArray[nClient].SetConnectFlag(TRUE);
LeaveCriticalSListen();
if (!g_ClientArray[nClient].Read())
{
g_ClientArray[nClient].Close(50000);
return -1;
}
#ifdef IOCP_DEBUG
char connectstr[128];
sprintf(connectstr,"%d client successed to connect %s \n",i,szPeerName);
//* OutputDebugString(connectstr);
#endif
return i;
}