2024-12-21 10:04:04 +08:00
|
|
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
#include <crtdbg.h>
|
|
|
|
|
|
#include <process.h>
|
|
|
|
|
|
#include <MMSystem.h>
|
|
|
|
|
|
#include "RUDPSocketFrame.h"
|
|
|
|
|
|
#include "Log.h"
|
|
|
|
|
|
#include "MemPool.h"
|
|
|
|
|
|
#include "PerfCheck.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned long GetTimeTick()
|
|
|
|
|
|
{
|
|
|
|
|
|
static int pivot = timeGetTime();
|
|
|
|
|
|
return timeGetTime() - pivot;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CRUDPSocketFrame::CRUDPSocketFrame()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_hSocket = INVALID_SOCKET;
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
InitializeCriticalSection(&m_CS);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
m_hThread = NULL;
|
|
|
|
|
|
m_bAlive = true;
|
|
|
|
|
|
m_iNetIDCnt = 1;
|
|
|
|
|
|
memset(m_nLastCheckTime, 0, sizeof(m_nLastCheckTime));
|
|
|
|
|
|
|
|
|
|
|
|
m_nThreadid = 0;
|
|
|
|
|
|
|
|
|
|
|
|
memset(m_szPublicIP, 0, sizeof(m_szPublicIP));
|
|
|
|
|
|
memset(m_szPrivateIP, 0, sizeof(m_szPrivateIP));
|
|
|
|
|
|
m_nPort = 0;
|
|
|
|
|
|
m_nCurTick = 0;
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
m_ProtectedSync = false;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
::srand(timeGetTime());
|
|
|
|
|
|
GetTimeTick();
|
|
|
|
|
|
|
|
|
|
|
|
#if defined( STRESS_TEST )
|
|
|
|
|
|
CRUDPConnect* pConnect = new CRUDPConnect( inet_addr("10.0.3.25"), htons(5000), 0 );
|
|
|
|
|
|
m_ConnectList[0] = pConnect;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
m_dwAffinityNum = INT_MAX;
|
|
|
|
|
|
m_bEnableAffinityCheck = false;
|
|
|
|
|
|
m_bClient = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CRUDPSocketFrame::~CRUDPSocketFrame()
|
|
|
|
|
|
{
|
|
|
|
|
|
Close();
|
|
|
|
|
|
_ASSERT(m_hThread == NULL); // <20>̰<EFBFBD><CCB0><EFBFBD><EFBFBD><EFBFBD> Assert <20>ѹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>...
|
|
|
|
|
|
_ASSERT(m_hSocket == INVALID_SOCKET);
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
DeleteCriticalSection(&m_CS);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int __stdcall CRUDPSocketFrame::_threadmain(void * pParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
((CRUDPSocketFrame*)pParam)->ThreadMain();
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::ThreadMain()
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef PRE_ADD_THREADAFFINITY
|
|
|
|
|
|
if (m_dwAffinityNum != INT_MAX)
|
|
|
|
|
|
{
|
|
|
|
|
|
DWORD dwNumber = GetCurrentProcessorNumber();
|
|
|
|
|
|
if (m_dwAffinityNum != dwNumber)
|
|
|
|
|
|
EnableAffinitySetting();
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif //#ifdef PRE_ADD_THREADAFFINITY
|
|
|
|
|
|
|
|
|
|
|
|
char buffer[1024*4];
|
|
|
|
|
|
int readbytes, addrlen;
|
|
|
|
|
|
unsigned long totalbytes, i;
|
|
|
|
|
|
unsigned long busytime;
|
|
|
|
|
|
SOCKADDR_IN addr;
|
|
|
|
|
|
fd_set fdset;
|
|
|
|
|
|
timeval tm;
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _SKIP_THREAD
|
|
|
|
|
|
while (m_bAlive)
|
|
|
|
|
|
#endif
|
|
|
|
|
|
{
|
|
|
|
|
|
// PROFILE_TIME_TEST_BLOCK_START( "CRUDPSocketFrame::ThreadMain()" );
|
|
|
|
|
|
tm.tv_sec = 0;
|
|
|
|
|
|
tm.tv_usec = _SELECT_TIMEOUT_SRV;
|
|
|
|
|
|
|
|
|
|
|
|
FD_ZERO(&fdset);
|
|
|
|
|
|
FD_SET(m_hSocket, &fdset);
|
|
|
|
|
|
|
|
|
|
|
|
m_nCurTick = GetTimeTick();
|
|
|
|
|
|
if (select(FD_SETSIZE, (fd_set*)&fdset, (fd_set*)0, (fd_set*)0, &tm) != SOCKET_ERROR)
|
|
|
|
|
|
{
|
|
|
|
|
|
busytime = GetCurTick() + _SELECT_BUSYTIME; //ó<><C3B3><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ÿ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|
|
|
|
|
//<2F><> <20>ʹ<EFBFBD> <20><><EFBFBD>Ƽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD>´<EFBFBD>.
|
|
|
|
|
|
if (fdset.fd_count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
do {
|
|
|
|
|
|
ioctlsocket(m_hSocket, FIONREAD, &totalbytes);
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < totalbytes && m_bAlive == true;)
|
|
|
|
|
|
{
|
|
|
|
|
|
addrlen = sizeof(addr);
|
|
|
|
|
|
readbytes = recvfrom(m_hSocket, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, &addrlen);
|
|
|
|
|
|
|
|
|
|
|
|
if (readbytes == SOCKET_ERROR)
|
|
|
|
|
|
{
|
|
|
|
|
|
int lasterr = GetLastError();
|
|
|
|
|
|
if (lasterr == WSAECONNRESET)
|
|
|
|
|
|
{
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
std::map <SOCKADDR_IN*, CRUDPConnect*, _addr_less_>::iterator ii = m_ConnectRef.find(&addr);
|
|
|
|
|
|
if (ii != m_ConnectRef.end() &&
|
|
|
|
|
|
(*ii).first->sin_addr.S_un.S_addr == addr.sin_addr.S_un.S_addr && (*ii).first->sin_port == addr.sin_port)
|
|
|
|
|
|
DisConnectPtr((*ii).second, false);
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
_tprintf(_T("<EFBFBD><EFBFBD><EFBFBD>ܺη<EFBFBD><EFBFBD><EFBFBD>!, %d (%d.%d.%d.%d)\n"), lasterr,
|
|
|
|
|
|
addr.sin_addr.S_un.S_un_b.s_b1, addr.sin_addr.S_un.S_un_b.s_b2,
|
|
|
|
|
|
addr.sin_addr.S_un.S_un_b.s_b3, addr.sin_addr.S_un.S_un_b.s_b4,
|
|
|
|
|
|
addr.sin_port);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
_tprintf(_T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~, %d (%d.%d.%d.%d)\n"), lasterr,
|
|
|
|
|
|
addr.sin_addr.S_un.S_un_b.s_b1, addr.sin_addr.S_un.S_un_b.s_b2,
|
|
|
|
|
|
addr.sin_addr.S_un.S_un_b.s_b3, addr.sin_addr.S_un.S_un_b.s_b4,
|
|
|
|
|
|
addr.sin_port); //oops!
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{//<2F><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3>
|
|
|
|
|
|
if (readbytes == 0) break;
|
|
|
|
|
|
i += readbytes;
|
|
|
|
|
|
Recv(buffer, readbytes, &addr);
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
//<2F>ʿ<EFBFBD><CABF>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7B8><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} while(totalbytes != 0 && GetTimeTick() < busytime);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
unsigned long curtime = GetCurTick();
|
|
|
|
|
|
|
|
|
|
|
|
TimeEvent();
|
|
|
|
|
|
if (m_bAlive == true && curtime - m_nLastCheckTime[2] >= _IDLE_PROCESS)
|
|
|
|
|
|
{//<2F><><EFBFBD><EFBFBD> <20>ְ<EFBFBD> <20><><EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD>μ<EFBFBD><CEBC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<>ٸ<EFBFBD>....
|
|
|
|
|
|
m_nLastCheckTime[2] = curtime;
|
|
|
|
|
|
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
if (curtime - m_nLastCheckTime[0] > _CHECK_UNREACHABLE)
|
|
|
|
|
|
{//<2F>߿<EFBFBD><DFBF><EFBFBD> <20><EFBFBD><DEBC><EFBFBD><EFBFBD>ε<EFBFBD> <20>Ҵٴ<D2B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϴ<EFBFBD>.
|
|
|
|
|
|
m_nLastCheckTime[0] = curtime;
|
|
|
|
|
|
CheckUnreachable(curtime);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><EFBFBD><DEBC><EFBFBD>ó<EFBFBD><C3B3> <20><>Ŷ<EFBFBD><C5B6> <20>Ҿ<EFBFBD>~ <20><><EFBFBD><EFBFBD><EFBFBD>ݴϴ<DDB4>.
|
|
|
|
|
|
#if !defined( STRESS_TEST )
|
|
|
|
|
|
FlushAck();
|
|
|
|
|
|
#endif
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
if (m_bClient)
|
|
|
|
|
|
{
|
|
|
|
|
|
static unsigned long s_nPreTick = 0;
|
|
|
|
|
|
if (s_nPreTick == 0)
|
|
|
|
|
|
s_nPreTick = curtime;
|
|
|
|
|
|
else if (s_nPreTick + (_PINGSENDTICK) < curtime)
|
|
|
|
|
|
{
|
|
|
|
|
|
PingCheck();
|
|
|
|
|
|
s_nPreTick = curtime;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (curtime - m_nLastCheckTime[1] > _CHECK_RECVTICK)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_nLastCheckTime[1] = curtime;
|
|
|
|
|
|
CheckRecvTick(curtime);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_bAlive == true)
|
|
|
|
|
|
{//<2F>߸<EFBFBD><DFB8>༮<EFBFBD><E0BCAE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߶<EFBFBD> <20>ݴϴ<DDB4>.
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
if (m_DisConnectList.size() > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
for (unsigned int j = 0; j < m_DisConnectList.size(); j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
ii = m_ConnectList.find(m_DisConnectList[j].second);
|
|
|
|
|
|
if (ii != m_ConnectList.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
DisConnectPtr((*ii).second, true, m_DisConnectList[j].first);
|
|
|
|
|
|
_ASSERT(m_ConnectList.find(m_DisConnectList[j].second) == m_ConnectList.end());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
m_DisConnectList.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
}
|
|
|
|
|
|
// PROFILE_TIME_TEST_BLOCK_END();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef PRE_ADD_THREADAFFINITY
|
|
|
|
|
|
void CRUDPSocketFrame::CheckAffinitySetting(DWORD dwTime)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_bEnableAffinityCheck && m_dwAffinityNum != INT_MAX)
|
|
|
|
|
|
{
|
|
|
|
|
|
DWORD dwNumber = GetCurrentProcessorNumber();
|
|
|
|
|
|
if (dwNumber != m_dwAffinityNum)
|
|
|
|
|
|
_SetThreadAffinityMask(m_dwAffinityNum);
|
|
|
|
|
|
|
|
|
|
|
|
m_bEnableAffinityCheck = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::EnableAffinitySetting()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_bEnableAffinityCheck = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif //#ifdef PRE_ADD_THREADAFFINITY
|
|
|
|
|
|
|
|
|
|
|
|
#include <Iprtrmib.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define CXIP_A(IP) ((IP&0xFF000000)>>24)
|
|
|
|
|
|
#define CXIP_B(IP) ((IP&0x00FF0000)>>16)
|
|
|
|
|
|
#define CXIP_C(IP) ((IP&0x0000FF00)>>8)
|
|
|
|
|
|
#define CXIP_D(IP) (IP&0x000000FF)
|
|
|
|
|
|
|
|
|
|
|
|
bool FileExists(const char* path)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::ifstream my_file(path);
|
|
|
|
|
|
if (my_file)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::GetHostAddr()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
if(FileExists(".\\RLKT\\IP.ini") == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
char PrivateIP[255];
|
|
|
|
|
|
char PublicIP[255];
|
|
|
|
|
|
printf("[RLKT]LOADING IP Data from file.\n");
|
|
|
|
|
|
GetPrivateProfileStringA("GameServer","PublicIP","127.0.0.1",PublicIP,255,".\\RLKT\\IP.ini");
|
|
|
|
|
|
GetPrivateProfileStringA("GameServer","PrivateIP","127.0.0.1",PrivateIP,255,".\\RLKT\\IP.ini");
|
|
|
|
|
|
|
|
|
|
|
|
strcpy(m_szPublicIP,PublicIP);
|
|
|
|
|
|
strcpy(m_szPrivateIP,PrivateIP);
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD dwPrivateIP = 0;
|
|
|
|
|
|
DWORD dwPrivateIPMask = 0;
|
|
|
|
|
|
DWORD dwPublicIP = 0;
|
|
|
|
|
|
DWORD dwPublicIPMask = 0;
|
|
|
|
|
|
|
|
|
|
|
|
HMODULE hIPHLP = LoadLibrary( _T("iphlpapi.dll") );
|
|
|
|
|
|
if( hIPHLP )
|
|
|
|
|
|
{
|
|
|
|
|
|
typedef BOOL (WINAPI * LPGIPT)(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder);
|
|
|
|
|
|
LPGIPT fnGetIpAddrTable=(LPGIPT)GetProcAddress(hIPHLP, "GetIpAddrTable");
|
|
|
|
|
|
if( fnGetIpAddrTable )
|
|
|
|
|
|
{
|
|
|
|
|
|
PMIB_IPADDRTABLE pIPAddrTable;
|
|
|
|
|
|
DWORD dwSize=0;
|
|
|
|
|
|
|
|
|
|
|
|
pIPAddrTable=(MIB_IPADDRTABLE *)malloc(sizeof(MIB_IPADDRTABLE));
|
|
|
|
|
|
if(!pIPAddrTable)
|
|
|
|
|
|
{
|
|
|
|
|
|
FreeLibrary(hIPHLP);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( fnGetIpAddrTable(pIPAddrTable, &dwSize, 0)==ERROR_INSUFFICIENT_BUFFER )
|
|
|
|
|
|
{
|
|
|
|
|
|
free(pIPAddrTable);
|
|
|
|
|
|
pIPAddrTable=(MIB_IPADDRTABLE *)malloc(dwSize);
|
|
|
|
|
|
if(!pIPAddrTable)
|
|
|
|
|
|
{
|
|
|
|
|
|
FreeLibrary(hIPHLP);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( fnGetIpAddrTable(pIPAddrTable, &dwSize, 0) == NO_ERROR )
|
|
|
|
|
|
{
|
|
|
|
|
|
for( DWORD i=0; i<pIPAddrTable->dwNumEntries ; ++i )
|
|
|
|
|
|
{
|
|
|
|
|
|
DWORD dwIP = ntohl(pIPAddrTable->table[i].dwAddr);
|
|
|
|
|
|
BOOL bPrivate = false;
|
|
|
|
|
|
|
|
|
|
|
|
if(CXIP_A(dwIP)==127)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(CXIP_A(dwIP)==10)
|
|
|
|
|
|
{
|
|
|
|
|
|
bPrivate=true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(CXIP_A(dwIP)==172)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(CXIP_B(dwIP)>=16 && CXIP_B(dwIP)<=31)
|
|
|
|
|
|
bPrivate=TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(CXIP_A(dwIP)==192)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if defined(_ID) // <20>ε<EFBFBD><CEB5>þ<D7BD> VPN 192.168.2 <20>뿪<EFBFBD><EBBFAA> <20>׳<EFBFBD> <20>о<EFBFBD><D0BE>մϴ<D5B4>.
|
|
|
|
|
|
if(CXIP_B(dwIP)==168)
|
|
|
|
|
|
{
|
|
|
|
|
|
if( CXIP_C(dwIP)==2)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
#else
|
|
|
|
|
|
if(CXIP_B(dwIP)==168)
|
|
|
|
|
|
{
|
|
|
|
|
|
#endif
|
|
|
|
|
|
bPrivate=TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(bPrivate)
|
|
|
|
|
|
{
|
|
|
|
|
|
if( !dwPrivateIP || dwPrivateIP>dwIP )
|
|
|
|
|
|
{
|
|
|
|
|
|
dwPrivateIP=dwIP;
|
|
|
|
|
|
dwPrivateIPMask=ntohl(pIPAddrTable->table[i].dwMask);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if( !dwPublicIP )
|
|
|
|
|
|
{
|
|
|
|
|
|
dwPublicIP=dwIP;
|
|
|
|
|
|
dwPublicIPMask=ntohl(pIPAddrTable->table[i].dwMask);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( dwPrivateIP && dwPublicIP)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
FreeLibrary(hIPHLP);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL bIPAdjust=FALSE;
|
|
|
|
|
|
// Check Public IP
|
|
|
|
|
|
if(dwPrivateIP && !dwPublicIP)
|
|
|
|
|
|
{
|
|
|
|
|
|
bIPAdjust=TRUE;
|
|
|
|
|
|
|
|
|
|
|
|
for(DWORD i=0; i<pIPAddrTable->dwNumEntries; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
DWORD dwIP=ntohl(pIPAddrTable->table[i].dwAddr);
|
|
|
|
|
|
BOOL bPrivate=FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
if(CXIP_A(dwIP)==127)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(CXIP_A(dwIP)==10)
|
|
|
|
|
|
{
|
|
|
|
|
|
bPrivate=TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(CXIP_A(dwIP)==172)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(CXIP_B(dwIP)>=16 && CXIP_B(dwIP)<=31)
|
|
|
|
|
|
bPrivate=TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(CXIP_A(dwIP)==192)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if defined(_ID) // <20>ε<EFBFBD><CEB5>þ<D7BD> VPN 192.168.2 <20>뿪<EFBFBD><EBBFAA> <20>׳<EFBFBD> <20>о<EFBFBD><D0BE>մϴ<D5B4>.
|
|
|
|
|
|
if(CXIP_B(dwIP)==168)
|
|
|
|
|
|
{
|
|
|
|
|
|
if( CXIP_C(dwIP)==2)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
#else
|
|
|
|
|
|
if(CXIP_B(dwIP)==168)
|
|
|
|
|
|
{
|
|
|
|
|
|
#endif
|
|
|
|
|
|
bPrivate=TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(bPrivate && dwPrivateIP!=dwIP)
|
|
|
|
|
|
{
|
|
|
|
|
|
dwPublicIP=dwIP;
|
|
|
|
|
|
dwPublicIPMask=ntohl(pIPAddrTable->table[i].dwMask);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check Not Found Public IP
|
|
|
|
|
|
if(!dwPublicIP)
|
|
|
|
|
|
{
|
|
|
|
|
|
dwPublicIP = dwPrivateIP;
|
|
|
|
|
|
dwPublicIPMask = dwPrivateIPMask;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if( bIPAdjust && dwPrivateIP>dwPublicIP )
|
|
|
|
|
|
{
|
|
|
|
|
|
DWORD dwIP = dwPrivateIP;
|
|
|
|
|
|
DWORD dwIPMask = dwPrivateIPMask;
|
|
|
|
|
|
|
|
|
|
|
|
dwPrivateIP = dwPublicIP;
|
|
|
|
|
|
dwPrivateIPMask = dwPublicIPMask;
|
|
|
|
|
|
dwPublicIP = dwIP;
|
|
|
|
|
|
dwPublicIPMask = dwIPMask;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Clear
|
|
|
|
|
|
free(pIPAddrTable);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
FreeLibrary(hIPHLP);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Free Libary
|
|
|
|
|
|
FreeLibrary(hIPHLP);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
printf("GetAddr Failed\n");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check IP
|
|
|
|
|
|
if(!dwPrivateIP && !dwPublicIP)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
DWORD dwNPublicIP = htonl(dwPublicIP);
|
|
|
|
|
|
_strcpy(m_szPublicIP, _countof(m_szPublicIP), inet_ntoa(*((in_addr*)&dwNPublicIP)), (int)strlen(inet_ntoa(*((in_addr*)&dwNPublicIP))) );
|
|
|
|
|
|
|
|
|
|
|
|
DWORD dwNPrivateIP = htonl(dwPrivateIP);
|
|
|
|
|
|
_strcpy(m_szPrivateIP, _countof(m_szPrivateIP), inet_ntoa(*((in_addr*)&dwNPrivateIP)), (int)strlen(inet_ntoa(*((in_addr*)&dwNPrivateIP))) );
|
|
|
|
|
|
|
|
|
|
|
|
printf("public [ip:%s]\n", m_szPublicIP);
|
|
|
|
|
|
printf("private [ip:%s]\n", m_szPrivateIP);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CRUDPSocketFrame::Open(int nID, int nAffinity, int iPort, bool bIsClient, bool bUseAffinity)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT(m_hSocket == INVALID_SOCKET && m_hThread == NULL);
|
|
|
|
|
|
m_hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
|
|
|
|
if (m_hSocket == INVALID_SOCKET) return false;
|
|
|
|
|
|
|
|
|
|
|
|
SOCKADDR_IN addr;
|
|
|
|
|
|
ZeroMemory(&addr, sizeof(addr));
|
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
|
|
addr.sin_port = htons(iPort);
|
|
|
|
|
|
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
|
|
|
|
|
|
|
|
|
|
|
|
if (::bind(m_hSocket, (struct sockaddr *)&addr, sizeof(addr)) == INVALID_SOCKET)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
DWORD dwMode = 1;
|
|
|
|
|
|
if (bIsClient)
|
|
|
|
|
|
dwMode = 0;
|
|
|
|
|
|
::ioctlsocket( m_hSocket, FIONBIO, &dwMode );
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
int len = sizeof(addr);
|
|
|
|
|
|
getsockname(m_hSocket, (struct sockaddr*)&addr, &len);
|
|
|
|
|
|
_tprintf(_T("UDP(port:%d)\n"), ntohs(addr.sin_port));
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
int SendBuf = 51200;
|
|
|
|
|
|
if (setsockopt(m_hSocket, SOL_SOCKET, SO_SNDBUF, (char*)&SendBuf, sizeof(SendBuf)) == SOCKET_ERROR){
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _SKIP_THREAD
|
|
|
|
|
|
m_hThread = (HANDLE) _beginthreadex(NULL, 0, _threadmain, (void*)this, 0, &m_nThreadid);
|
|
|
|
|
|
if (bIsClient == false && bUseAffinity == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_dwAffinityNum = nAffinity;
|
|
|
|
|
|
if (_SetThreadAffinityMask(m_dwAffinityNum) == false)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
m_bClient = bIsClient;
|
|
|
|
|
|
m_nPort = iPort;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::Close()
|
|
|
|
|
|
{//die die
|
|
|
|
|
|
|
|
|
|
|
|
// while(m_hThread != NULL)
|
|
|
|
|
|
//{
|
|
|
|
|
|
m_bAlive = false;
|
|
|
|
|
|
if (WaitForSingleObject(m_hThread, 2000) != WAIT_TIMEOUT)
|
|
|
|
|
|
{
|
|
|
|
|
|
if( m_hThread ) {
|
|
|
|
|
|
CloseHandle(m_hThread);
|
|
|
|
|
|
m_hThread = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
_ASSERT(0);
|
|
|
|
|
|
//}
|
|
|
|
|
|
//if( !m_hThread ) m_bAlive = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (m_hSocket != INVALID_SOCKET)
|
|
|
|
|
|
{
|
|
|
|
|
|
closesocket(m_hSocket);
|
|
|
|
|
|
m_hSocket = INVALID_SOCKET;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
for (ii = m_ConnectList.begin(); ii != m_ConnectList.end(); ii++)
|
|
|
|
|
|
delete (*ii).second;
|
|
|
|
|
|
m_ConnectList.clear();
|
|
|
|
|
|
m_ConnectRef.clear();
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CRUDPSocketFrame::_SetThreadAffinityMask(DWORD dwAffinityMask)
|
|
|
|
|
|
{
|
|
|
|
|
|
DWORD_PTR dwMask = SetThreadAffinityMask(m_hThread, 1 << dwAffinityMask);
|
|
|
|
|
|
if (dwMask == ERROR)
|
|
|
|
|
|
{
|
|
|
|
|
|
DWORD dwError = GetLastError();
|
|
|
|
|
|
if (dwError == ERROR_INVALID_PARAMETER)
|
|
|
|
|
|
g_Log.Log(LogType::_FILELOG, L"Invalid thread mask parameter");
|
|
|
|
|
|
else
|
|
|
|
|
|
g_Log.Log(LogType::_FILELOG, L"Invalid thread mask error [%d]", dwError);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CRUDPSocketFrame::Connect(const char * pIP, int iPort)
|
|
|
|
|
|
{
|
|
|
|
|
|
CRUDPConnect * con = Connect(inet_addr(pIP), htons(iPort));
|
|
|
|
|
|
return con->GetID();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::DisConnect(int iNetID)
|
|
|
|
|
|
{//<2F>ܺο<DCBA><CEBF><EFBFBD> ȣ<><C8A3><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20>༮<EFBFBD>Դϴ<D4B4>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>⸸ <20>ϰ<EFBFBD> <20>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
ii = m_ConnectList.find(iNetID);
|
|
|
|
|
|
if (ii != m_ConnectList.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
for (i = 0; i < m_DisConnectList.size(); i++)
|
|
|
|
|
|
if (m_DisConnectList[i].second == iNetID)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
if (i == m_DisConnectList.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
_RELIABLE_UDP_HEADER ack;
|
|
|
|
|
|
ack.combo = _PACKET_HEADER(7, 0);
|
|
|
|
|
|
ack.crc = 0;
|
|
|
|
|
|
ack.crc = CRUDPConnect::GetCRC((unsigned char*)&ack, sizeof(ack));
|
|
|
|
|
|
SendTo(&ack, sizeof(ack), (*ii).second->GetAddr());
|
|
|
|
|
|
SendTo(&ack, sizeof(ack), (*ii).second->GetAddr());
|
|
|
|
|
|
|
|
|
|
|
|
m_DisConnectList.push_back(std::make_pair(false, iNetID));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::DisConnectAsync(int iNetID)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
|
|
ii = m_ConnectList.find(iNetID);
|
|
|
|
|
|
if (ii != m_ConnectList.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
for (i = 0; i < m_DisConnectList.size(); i++)
|
|
|
|
|
|
if (m_DisConnectList[i].second == iNetID)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
if (i == m_DisConnectList.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
_RELIABLE_UDP_HEADER ack;
|
|
|
|
|
|
ack.combo = _PACKET_HEADER(7, 0);
|
|
|
|
|
|
ack.crc = 0;
|
|
|
|
|
|
ack.crc = CRUDPConnect::GetCRC((unsigned char*)&ack, sizeof(ack));
|
|
|
|
|
|
SendTo(&ack, sizeof(ack), (*ii).second->GetAddr());
|
|
|
|
|
|
SendTo(&ack, sizeof(ack), (*ii).second->GetAddr());
|
|
|
|
|
|
|
|
|
|
|
|
m_DisConnectList.push_back(std::make_pair(true, iNetID));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CRUDPSocketFrame::Send(int iNetID, void * data, int len, int prior)
|
|
|
|
|
|
{//<2F>ܺο<DCBA><CEBF><EFBFBD> ȣ<><C8A3><EFBFBD><EFBFBD> <20>˴ϴ<CBB4>. <20><><EFBFBD><EFBFBD>ȭ <20><><EFBFBD><EFBFBD>!
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
ii = m_ConnectList.find(iNetID);
|
|
|
|
|
|
if (ii != m_ConnectList.end())
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
_ASSERT(prior<3);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
ret = (*ii).second->Send(data, len, prior, this);
|
|
|
|
|
|
}
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::SendTo(void * data, int len, SOCKADDR_IN * addr)
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _SEND_CHECK
|
|
|
|
|
|
static int _lastchecktime = 0;
|
|
|
|
|
|
static int _sendbytes = 0, _cnt = 0;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
int ret = sendto(m_hSocket, (char*)data, len, 0, (struct sockaddr*)addr, sizeof(SOCKADDR_IN));
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _SEND_CHECK
|
|
|
|
|
|
if (m_bClient == false && ret == SOCKET_ERROR)
|
|
|
|
|
|
{
|
|
|
|
|
|
DWORD err = GetLastError();
|
|
|
|
|
|
_tprintf(_T("UDPSENDERR %d\n"), GetLastError());
|
|
|
|
|
|
}
|
|
|
|
|
|
_sendbytes += len;
|
|
|
|
|
|
_cnt++;
|
|
|
|
|
|
if (GetCurTick()- _lastchecktime > 10*1000)
|
|
|
|
|
|
{
|
|
|
|
|
|
_tprintf(_T("SERVER UDP [S %d:%d:%d]\n"), _sendbytes * 1000 / (GetCurTick() - _lastchecktime), _sendbytes, _cnt);
|
|
|
|
|
|
_lastchecktime = GetCurTick();
|
|
|
|
|
|
_sendbytes = 0;
|
|
|
|
|
|
_cnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CRUDPSocketFrame::CheckPacket(const void * data, int len, void * outbuf)
|
|
|
|
|
|
{//<2F><>Ŷ<EFBFBD><C5B6> üũ<C3BC>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
|
|
|
|
|
|
_RELIABLE_UDP_HEADER * header = (_RELIABLE_UDP_HEADER*)data;
|
|
|
|
|
|
|
|
|
|
|
|
if (len <= sizeof(_RELIABLE_UDP_HEADER)) return 0;
|
|
|
|
|
|
unsigned char crc = header->crc, crc2;
|
|
|
|
|
|
header->crc = 0;
|
|
|
|
|
|
crc2 = CRUDPConnect::GetCRC((unsigned char*)data, len);
|
|
|
|
|
|
header->crc = crc;
|
|
|
|
|
|
if (crc != crc2) return 0;
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(outbuf, &header[1], len - sizeof(_RELIABLE_UDP_HEADER));
|
|
|
|
|
|
return len - sizeof(_RELIABLE_UDP_HEADER);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CRUDPConnect * CRUDPSocketFrame::Connect(unsigned long iIP, int iPort)
|
|
|
|
|
|
{
|
|
|
|
|
|
CRUDPConnect * con = NULL;
|
|
|
|
|
|
int id;
|
|
|
|
|
|
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
id = m_iNetIDCnt++;
|
|
|
|
|
|
con = new CRUDPConnect(iIP, iPort, id);
|
|
|
|
|
|
|
|
|
|
|
|
if (m_iNetIDCnt == 0) m_iNetIDCnt++;
|
|
|
|
|
|
_ASSERT(m_ConnectList.find(con->GetID()) == m_ConnectList.end());
|
|
|
|
|
|
m_ConnectList[con->GetID()] = con;
|
|
|
|
|
|
m_ConnectRef[con->GetAddr()] = con;
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
return con;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::DisConnectPtr(CRUDPConnect * pCon, bool bForce, bool bUnreachable)
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20>Ǵ<EFBFBD> <20>Լ<EFBFBD>
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(m_ProtectedSync == true);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if defined( STRESS_TEST )
|
|
|
|
|
|
return;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
std::map<int, CRUDPConnect*>::iterator itor = m_ConnectList.find( pCon->GetID() );
|
|
|
|
|
|
if( itor != m_ConnectList.end())
|
|
|
|
|
|
m_ConnectList.erase( itor );
|
|
|
|
|
|
|
|
|
|
|
|
std::map<SOCKADDR_IN*,CRUDPConnect*,_addr_less_>::iterator itor2 = m_ConnectRef.find(pCon->GetAddr());
|
|
|
|
|
|
if ( itor2 != m_ConnectRef.end())
|
|
|
|
|
|
m_ConnectRef.erase( itor2 );
|
|
|
|
|
|
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(m_ProtectedSync == false);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
DisConnected(pCon->GetID(), bForce, bUnreachable);
|
|
|
|
|
|
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
delete pCon;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::Recv(void * pData, int iLen, SOCKADDR_IN * pAddr)
|
|
|
|
|
|
{//<2F><><EFBFBD><EFBFBD>ȭ <20><><EFBFBD><EFBFBD>!
|
|
|
|
|
|
_RELIABLE_UDP_HEADER * header = (_RELIABLE_UDP_HEADER*)pData;
|
|
|
|
|
|
std::map <SOCKADDR_IN*, CRUDPConnect*, _addr_less_>::iterator ii;
|
|
|
|
|
|
CRUDPConnect * con = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
Enter();
|
|
|
|
|
|
ii = m_ConnectRef.find(pAddr);
|
|
|
|
|
|
if (ii != m_ConnectRef.end() && (*ii).first->sin_addr.S_un.S_addr == pAddr->sin_addr.S_un.S_addr && (*ii).first->sin_port == pAddr->sin_port)
|
|
|
|
|
|
con = (*ii).second;
|
|
|
|
|
|
Leave();
|
|
|
|
|
|
|
|
|
|
|
|
if (con == NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(m_ProtectedSync == false);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
if (Accept(m_iNetIDCnt, pAddr, pData, iLen) == false) return;
|
|
|
|
|
|
con = Connect(pAddr->sin_addr.S_un.S_addr, pAddr->sin_port);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_ASSERT(con);
|
|
|
|
|
|
con->Recv(pData, iLen, this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::CheckUnreachable(unsigned long nCurTick)
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(m_ProtectedSync == true);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
return; //debug<75><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ<C3BC><C5A9><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>.
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if defined( STRESS_TEST )
|
|
|
|
|
|
return;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
for (ii = m_ConnectList.begin(); ii != m_ConnectList.end(); ii++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((*ii).second->CheckUnreachable(nCurTick, this) == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _GAMESERVER
|
|
|
|
|
|
g_Log.Log( LogType::_UNREACHABLE, L"[CRUDPSocketFrame::CheckUnreachable] NetID=%d SendQueueSize=%d", (*ii).second->GetID(), (*ii).second->GetSendQueueSize() );
|
|
|
|
|
|
#endif
|
|
|
|
|
|
DisConnectAsync((*ii).second->GetID());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::CheckRecvTick(unsigned long nCurTick)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if defined( STRESS_TEST )
|
|
|
|
|
|
return;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(m_ProtectedSync == true);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
return; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ<C3BC><C5A9><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>.
|
|
|
|
|
|
#endif
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
for (ii = m_ConnectList.begin(); ii != m_ConnectList.end(); ii++)
|
|
|
|
|
|
if ((*ii).second->CheckRecvTick(nCurTick) == false)
|
|
|
|
|
|
DisConnectAsync((*ii).second->GetID());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::FlushAck()
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(m_ProtectedSync == true);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
for (ii = m_ConnectList.begin(); ii != m_ConnectList.end(); ii++)
|
|
|
|
|
|
(*ii).second->FlushAck(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::PingCheck()
|
|
|
|
|
|
{
|
|
|
|
|
|
if( !m_ConnectList.empty() )
|
|
|
|
|
|
{
|
|
|
|
|
|
std::map <int, CRUDPConnect*>::iterator ii;
|
|
|
|
|
|
for (ii = m_ConnectList.begin(); ii != m_ConnectList.end(); ii++)
|
|
|
|
|
|
(*ii).second->PingCheck(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::Enter()
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
EnterCriticalSection(&m_CS);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(m_ProtectedSync == false);
|
|
|
|
|
|
m_ProtectedSync = true;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPSocketFrame::Leave()
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(m_ProtectedSync == true);
|
|
|
|
|
|
m_ProtectedSync = false;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
LeaveCriticalSection(&m_CS);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Class : CRUDPConnect //
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
CRUDPConnect::CRUDPConnect(unsigned long iIP, int iPort, int iNetID)
|
|
|
|
|
|
{
|
|
|
|
|
|
memset(&m_TargetAddr, 0, sizeof(SOCKADDR_IN));
|
|
|
|
|
|
m_TargetAddr.sin_family = AF_INET;
|
|
|
|
|
|
m_TargetAddr.sin_port = iPort;
|
|
|
|
|
|
m_TargetAddr.sin_addr.S_un.S_addr = iIP;
|
|
|
|
|
|
|
|
|
|
|
|
m_iNetID = iNetID;
|
|
|
|
|
|
m_cUnreachableCnt = 0;
|
|
|
|
|
|
memset(m_AckList, 0, sizeof(m_AckList));
|
|
|
|
|
|
memset(m_AckListCnt, 0, sizeof(m_AckListCnt));
|
|
|
|
|
|
m_RTOTick = _RESEND_TIME;
|
|
|
|
|
|
m_SeqCnt = 0;
|
|
|
|
|
|
m_AckCnt = 0;
|
|
|
|
|
|
m_FastCnt = 0;
|
|
|
|
|
|
m_RecvFastCnt = 0;
|
|
|
|
|
|
m_RecvSeqCnt = 0;
|
|
|
|
|
|
m_RecvAckCnt = 0;
|
|
|
|
|
|
m_RecvTick = 0;
|
|
|
|
|
|
|
|
|
|
|
|
m_lastchecktime = 0;
|
|
|
|
|
|
m_sendbytes = m_cnt = 0;
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
memset(m_nDebugPriorCnt, 0, sizeof(m_nDebugPriorCnt));
|
|
|
|
|
|
#endif
|
|
|
|
|
|
m_uiRTOTick = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CRUDPConnect::~CRUDPConnect()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (unsigned int i = 0; i < m_AllocedQueue.size(); i++)
|
|
|
|
|
|
SAFE_DELETEA(m_AllocedQueue[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CRUDPConnect::CheckUnreachable(unsigned long iTimeTick, CRUDPSocketFrame * pSocket)
|
|
|
|
|
|
{//<2F>Ҵٴ<D2B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(pSocket->m_ProtectedSync == true);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef NDEBUG
|
|
|
|
|
|
#ifndef _RDEBUG
|
|
|
|
|
|
if (_RTO_LIST_MAX < m_SendQueue.size()) //<2F><><EFBFBD>̴<EFBFBD> <20><EFBFBD><DEBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>þ<C3BE><EEB3AA> <20>ȵ<EFBFBD>!
|
|
|
|
|
|
{
|
|
|
|
|
|
if( m_uiRTOTick == 0 )
|
|
|
|
|
|
{
|
|
|
|
|
|
m_uiRTOTick = iTimeTick;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if( iTimeTick - m_uiRTOTick >= _RTO_TICK_MAX )
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m_cUnreachableCnt = 0;
|
|
|
|
|
|
m_uiRTOTick = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif // #ifndef _RDEBUG
|
|
|
|
|
|
#endif // #ifdef NDEBUG
|
|
|
|
|
|
|
|
|
|
|
|
std::list <_PACKET_QUEUE*>::iterator ii;
|
|
|
|
|
|
for (ii = m_SendQueue.begin(); ii != m_SendQueue.end(); ii++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (iTimeTick - (*ii)->tick >= m_RTOTick)
|
|
|
|
|
|
{
|
|
|
|
|
|
pSocket->SendTo((*ii)->data, (*ii)->len, &m_TargetAddr);
|
|
|
|
|
|
(*ii)->tick = iTimeTick;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CRUDPConnect::CheckRecvTick(unsigned long nCurTick)
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef NDEBUG
|
|
|
|
|
|
#ifndef _RDEBUG
|
|
|
|
|
|
if (nCurTick > m_RecvTick + _CHECK_RECVTICK)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPConnect::FlushAck(CRUDPSocketFrame * pSocket)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_AckListCnt[i] > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT(m_AckListCnt[i] <= 16);
|
|
|
|
|
|
unsigned char packet[sizeof(_RELIABLE_UDP_HEADER) + 16 * 2];
|
|
|
|
|
|
_RELIABLE_UDP_HEADER * _packet = (_RELIABLE_UDP_HEADER*)packet;
|
|
|
|
|
|
|
|
|
|
|
|
_packet->combo = _PACKET_HEADER((i+4), (m_AckListCnt[i] << 3));
|
|
|
|
|
|
memcpy(packet + sizeof(_RELIABLE_UDP_HEADER), m_AckList[i], m_AckListCnt[i]*2);
|
|
|
|
|
|
|
|
|
|
|
|
_packet->crc = 0;
|
|
|
|
|
|
_packet->crc = GetCRC(packet, sizeof(_RELIABLE_UDP_HEADER) + m_AckListCnt[i] * 2);
|
|
|
|
|
|
|
|
|
|
|
|
pSocket->SendTo(packet, sizeof(_RELIABLE_UDP_HEADER) + m_AckListCnt[i] * 2, &m_TargetAddr);
|
|
|
|
|
|
m_AckListCnt[i] = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPConnect::PingCheck(CRUDPSocketFrame * pSocket)
|
|
|
|
|
|
{
|
|
|
|
|
|
_RELIABLE_UDP_HEADER packet;
|
|
|
|
|
|
memset(&packet, 0, sizeof(packet));
|
|
|
|
|
|
|
|
|
|
|
|
packet.combo = _PACKET_HEADER(3, 0);
|
|
|
|
|
|
packet.crc = 0;
|
|
|
|
|
|
packet.crc = GetCRC((unsigned char*)&packet, sizeof(packet));
|
|
|
|
|
|
|
|
|
|
|
|
pSocket->SendTo(&packet, sizeof(packet), &m_TargetAddr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CRUDPConnect::Send(void * pData, int iLen, int iPrior, CRUDPSocketFrame * pSocket)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT(iLen < 512); //512<31><32><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>մϴٸ<CFB4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 256<35><36><EFBFBD>Ϸ<EFBFBD> <20>ۼ<EFBFBD><DBBC><EFBFBD><EFBFBD>ּ<EFBFBD><D6BC><EFBFBD>.
|
|
|
|
|
|
unsigned char buffer[512 + sizeof(_RELIABLE_UDP_HEADER)];
|
|
|
|
|
|
_RELIABLE_UDP_HEADER * header = (_RELIABLE_UDP_HEADER*)buffer;
|
|
|
|
|
|
|
|
|
|
|
|
//if (iLen > sizeof(buffer) + sizeof(_RELIABLE_UDP_HEADER)) return -1;
|
|
|
|
|
|
if (iLen > sizeof(buffer) - sizeof(_RELIABLE_UDP_HEADER)) return -1;
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
header->flags = 0x00;
|
|
|
|
|
|
if (iPrior == _FAST)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT((m_FastCnt&0x07) == 0);
|
|
|
|
|
|
header->combo = _PACKET_HEADER(_FAST, m_FastCnt);
|
|
|
|
|
|
m_FastCnt += 8;
|
|
|
|
|
|
} else
|
|
|
|
|
|
if (iPrior == _RELIABLE_NOORDER)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT((m_AckCnt&0x07) == 0);
|
|
|
|
|
|
header->combo = _PACKET_HEADER(_RELIABLE_NOORDER, m_AckCnt);
|
|
|
|
|
|
m_AckCnt += 8;
|
|
|
|
|
|
} else
|
|
|
|
|
|
if (iPrior == _RELIABLE)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT((m_SeqCnt&0x07) == 0);
|
|
|
|
|
|
header->combo = _PACKET_HEADER(_RELIABLE, m_SeqCnt);
|
|
|
|
|
|
m_SeqCnt += 8;
|
|
|
|
|
|
} else
|
|
|
|
|
|
return -1; //<2F><><EFBFBD><EFBFBD>?
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Դϴ<D4B4>.
|
|
|
|
|
|
memcpy(buffer + sizeof(_RELIABLE_UDP_HEADER), pData, iLen);
|
|
|
|
|
|
header->crc = 0;
|
|
|
|
|
|
header->crc = GetCRC(buffer, sizeof(_RELIABLE_UDP_HEADER) + iLen);
|
|
|
|
|
|
|
|
|
|
|
|
//Ȯ<><C8AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ϴ<EFBFBD> <20><EFBFBD><DEBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ť<><C5A5> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
|
|
|
|
|
#if defined( STRESS_TEST )
|
|
|
|
|
|
iPrior = _FAST;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (iPrior != _FAST)
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#ifdef _SYNC_RUDP
|
|
|
|
|
|
_ASSERT(pSocket->m_ProtectedSync == true);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
_PACKET_QUEUE * pQueue = CreateQueue(pSocket, buffer, sizeof(_RELIABLE_UDP_HEADER) + iLen, iPrior == _RELIABLE_NOORDER ? 4 : 5);
|
|
|
|
|
|
if (pQueue == NULL) return -1;
|
|
|
|
|
|
m_SendQueue.push_back(pQueue);
|
|
|
|
|
|
if ((!(m_AckCnt&(7*8)) || !(m_SeqCnt&(7*8))) && m_RTOTick > 100)
|
|
|
|
|
|
m_RTOTick -= 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ôپ<C3B4>~
|
|
|
|
|
|
pSocket->SendTo(buffer, sizeof(_RELIABLE_UDP_HEADER) + iLen, &m_TargetAddr);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
m_nDebugPriorCnt[iPrior]++;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _SEND_CHECK
|
|
|
|
|
|
m_sendbytes += sizeof(_RELIABLE_UDP_HEADER) + iLen;
|
|
|
|
|
|
m_cnt++;
|
|
|
|
|
|
if (pSocket->GetCurTick()- m_lastchecktime > 60*1000)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD> 4K Bytes<65><73> <20>Ѿ<D1BE><EEB0A1> Output
|
|
|
|
|
|
if (m_sendbytes * 1000 / (pSocket->GetCurTick() - m_lastchecktime) > (1024 * 4))
|
|
|
|
|
|
_tprintf(_T("INDIVIDUAL UDP [S %d : C %d]\n"), m_sendbytes * 1000 / (pSocket->GetCurTick() - m_lastchecktime), m_cnt);
|
|
|
|
|
|
m_lastchecktime = pSocket->GetCurTick();
|
|
|
|
|
|
m_sendbytes = 0;
|
|
|
|
|
|
m_cnt = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return iLen;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPConnect::Recv(void * pData, int iLen, CRUDPSocketFrame * pSocket)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned long nCurTick = pSocket->GetCurTick();
|
|
|
|
|
|
m_RecvTick = nCurTick;
|
|
|
|
|
|
|
|
|
|
|
|
_RELIABLE_UDP_HEADER * header = (_RELIABLE_UDP_HEADER*)pData;
|
|
|
|
|
|
if (iLen < sizeof(_RELIABLE_UDP_HEADER))
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
unsigned char crc = header->crc;
|
|
|
|
|
|
header->crc = 0;
|
|
|
|
|
|
if (crc != GetCRC((unsigned char*)pData, iLen))
|
|
|
|
|
|
{
|
|
|
|
|
|
//_tprintf(_T("recv err\n"));
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch(_PACKET_TYPE(header->flags))
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0: {
|
|
|
|
|
|
// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>༮<EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD> (<28>ֱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>༮)
|
|
|
|
|
|
if (((_PACKET_SEQ(header->seq) < m_RecvFastCnt && (int)_PACKET_SEQ(header->seq) + 0x8000 > (int)m_RecvFastCnt) ||
|
|
|
|
|
|
(_PACKET_SEQ(header->seq) > m_RecvFastCnt && (int)_PACKET_SEQ(header->seq) - 0x8000 > (int)m_RecvFastCnt)))
|
|
|
|
|
|
return ;
|
|
|
|
|
|
pSocket->Recv(m_iNetID, (char*)pData + sizeof(_RELIABLE_UDP_HEADER), iLen - sizeof(_RELIABLE_UDP_HEADER));
|
|
|
|
|
|
m_RecvFastCnt += 8;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case 1 : {
|
|
|
|
|
|
std::list <unsigned short>::iterator ii;
|
|
|
|
|
|
int lastcnt;
|
|
|
|
|
|
|
|
|
|
|
|
// ack<63><6B>ȣ<EFBFBD><C8A3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SendAck(0x04, _PACKET_ACK(header->ack), &m_TargetAddr, pSocket);
|
|
|
|
|
|
// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>༮<EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD> (<28>ֱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>༮)
|
|
|
|
|
|
if (((_PACKET_SEQ(header->seq) < m_RecvAckCnt && (int)_PACKET_SEQ(header->seq) + 0x8000 > (int)m_RecvAckCnt) ||
|
|
|
|
|
|
(_PACKET_SEQ(header->seq) > m_RecvAckCnt && (int)_PACKET_SEQ(header->seq) - 0x8000 > (int)m_RecvAckCnt)))
|
|
|
|
|
|
return ;
|
|
|
|
|
|
|
|
|
|
|
|
// <09>ֱ<EFBFBD> <20>༮<EFBFBD><E0BCAE> <20>ƴϸ<C6B4> <20>Ҵٴ<D2B4> ǥ<>ø<EFBFBD> <20>صд<D8B5>. (<28><><EFBFBD><EFBFBD> ǥ<>ð<EFBFBD> <20>Ǿ<EFBFBD> <20>ִٸ<D6B4> <20>Ҵ<DEBE> <20>༮)
|
|
|
|
|
|
if (m_RecvAckCnt != _PACKET_ACK(header->ack))
|
|
|
|
|
|
{
|
|
|
|
|
|
//std::list <unsigned short> ::iterator ii;
|
|
|
|
|
|
for(ii=m_AckQueue.begin(); ii!=m_AckQueue.end(); ii++)
|
|
|
|
|
|
if ((*ii) == _PACKET_ACK(header->ack))
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
m_AckQueue.push_back(_PACKET_ACK(header->ack));
|
|
|
|
|
|
} else
|
|
|
|
|
|
{ // <09>ֱ<EFBFBD> <20>༮<EFBFBD>̹Ƿ<CCB9> <20>Ҵٴ<D2B4> ǥ<><C7A5><EFBFBD>صΰ<D8B5>, <20>̹<EFBFBD> <20><EFBFBD> <20>༮<EFBFBD><E0BCAE> <20>߿<EFBFBD><DFBF><EFBFBD> <20><><EFBFBD><EFBFBD> <20>༮<EFBFBD><E0BCAE> <20>ִ<EFBFBD><D6B4><EFBFBD> <20>˻<EFBFBD>
|
|
|
|
|
|
m_RecvAckCnt += 8;
|
|
|
|
|
|
do {
|
|
|
|
|
|
lastcnt = m_RecvAckCnt;
|
|
|
|
|
|
for(ii=m_AckQueue.begin(); ii!=m_AckQueue.end(); ii++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((*ii) == m_RecvAckCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_AckQueue.erase(ii);
|
|
|
|
|
|
m_RecvAckCnt += 8;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} while(lastcnt != m_RecvAckCnt);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><EFBFBD><DEBC><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3>.
|
|
|
|
|
|
pSocket->Recv(m_iNetID, (char*)pData + sizeof(_RELIABLE_UDP_HEADER), iLen - sizeof(_RELIABLE_UDP_HEADER));
|
|
|
|
|
|
break ;
|
|
|
|
|
|
}
|
|
|
|
|
|
case 2 : {
|
|
|
|
|
|
// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3
|
|
|
|
|
|
|
|
|
|
|
|
// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>༮<EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD>...
|
|
|
|
|
|
// (<28><><EFBFBD><EFBFBD><EFBFBD>ʿ<EFBFBD><CABF><EFBFBD> ack <20><>ȣ<EFBFBD><C8A3> <20><><EFBFBD><EFBFBD><DEBE><EFBFBD> <20><><EFBFBD><EFBFBD>...)
|
|
|
|
|
|
// (<28>ֱ<EFBFBD> 32767<36><37>° <20><><EFBFBD>ϸ<EFBFBD> <20><>ȿ<EFBFBD><C8BF>)
|
|
|
|
|
|
if (((_PACKET_SEQ(header->seq) < m_RecvSeqCnt && (int)_PACKET_SEQ(header->seq) + 0x8000 > (int)m_RecvSeqCnt) ||
|
|
|
|
|
|
(_PACKET_SEQ(header->seq) > m_RecvSeqCnt && (int)_PACKET_SEQ(header->seq) - 0x8000 > (int)m_RecvSeqCnt)))
|
|
|
|
|
|
{
|
|
|
|
|
|
// <09>Ҿ<DEBE><D2BE><EFBFBD>~ : ack <20><>ȣ<EFBFBD><C8A3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SendAck(0x05, _PACKET_ACK(header->ack), &m_TargetAddr, pSocket);
|
|
|
|
|
|
return ;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <09><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20>ƴ϶<C6B4><CFB6><EFBFBD> ť<><C5A5> <20>ִ´<D6B4>.(<28><> ť<><C5A5> <20>̹<EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
|
|
|
|
|
if (m_RecvSeqCnt != _PACKET_SEQ(header->seq))
|
|
|
|
|
|
{// m_RecvQueue <20><> recv <20>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD><EFBFBD> ȣ<><C8A3><EFBFBD>Ǹ<EFBFBD> recv <20><> <20>ϳ<EFBFBD><CFB3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>忡<EFBFBD><E5BFA1><EFBFBD><EFBFBD> ȣ<><C8A3><EFBFBD>ǹǷ<C7B9> <20><><EFBFBD><EFBFBD>ȭ <20><><EFBFBD>ʿ<EFBFBD>!
|
|
|
|
|
|
std::list <_PACKET_QUEUE*> ::iterator ii;
|
|
|
|
|
|
for(ii=m_RecvQueue.begin(); ii!=m_RecvQueue.end(); ii++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((*ii)->seq == _PACKET_SEQ(header->seq))
|
|
|
|
|
|
{
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
_ASSERT(memcmp((*ii)->data, pData, iLen) == 0);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
// <09>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD>³<C2B3>. <20>Ҿ<DEBE><D2BE><EFBFBD>~ : ack <20><>ȣ<EFBFBD><C8A3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SendAck(0x05, _PACKET_ACK(header->ack), &m_TargetAddr, pSocket);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD>Ҿ<DEBE><D2BE><EFBFBD>.
|
|
|
|
|
|
SendAck(0x06, _PACKET_ACK(header->ack), &m_TargetAddr, pSocket);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>߰<EFBFBD><DFB0><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Դ<EFBFBD>. <20>ϴ<EFBFBD> ť<><C5A5> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>
|
|
|
|
|
|
pSocket->Enter();
|
|
|
|
|
|
_PACKET_QUEUE * pQueue = CreateQueue(pSocket, pData, iLen);
|
|
|
|
|
|
if (pQueue != NULL)
|
|
|
|
|
|
m_RecvQueue.push_back(pQueue);
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F><DEB8> <20><><EFBFBD> ť<><C5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ѱ<EFBFBD><D1B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD> <20>Ұ<EFBFBD><D2B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
pSocket->DisConnectPtr(this, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
pSocket->Leave();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> ack<63><6B>ȣ<EFBFBD><C8A3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|
|
|
|
|
// <09>Ҿ<DEBE><D2BE><EFBFBD>~ : ack <20><>ȣ<EFBFBD><C8A3> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
SendAck(0x05, _PACKET_ACK(header->ack), &m_TargetAddr, pSocket);
|
|
|
|
|
|
|
|
|
|
|
|
// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>ϰ<EFBFBD> ť<><C5A5><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>͵<EFBFBD><CDB5><EFBFBD> <20>ִ<EFBFBD> <20><> ã<>´<EFBFBD>
|
|
|
|
|
|
m_RecvSeqCnt += 8;
|
|
|
|
|
|
pSocket->Recv(m_iNetID, (char*)pData + sizeof(_RELIABLE_UDP_HEADER), iLen - sizeof(_RELIABLE_UDP_HEADER));
|
|
|
|
|
|
// <20>ӽ<EFBFBD> Siva
|
|
|
|
|
|
if( !pSocket->IsAlive() ) break;
|
|
|
|
|
|
|
|
|
|
|
|
// <09><>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>༮<EFBFBD><E0BCAE><EFBFBD><EFBFBD> ã<>Ƽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>
|
|
|
|
|
|
unsigned short lastcnt;
|
|
|
|
|
|
do {
|
|
|
|
|
|
std::list <_PACKET_QUEUE*> ::iterator ii;
|
|
|
|
|
|
lastcnt = m_RecvSeqCnt;
|
|
|
|
|
|
for(ii=m_RecvQueue.begin(); ii!=m_RecvQueue.end(); ii++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_PACKET_SEQ((*ii)->seq) == m_RecvSeqCnt)
|
|
|
|
|
|
{
|
|
|
|
|
|
pSocket->Recv(m_iNetID, (char*)(*ii)->data + sizeof(_RELIABLE_UDP_HEADER), (*ii)->len - sizeof(_RELIABLE_UDP_HEADER));
|
|
|
|
|
|
pSocket->Enter();
|
|
|
|
|
|
ReleaseQueue(*ii);
|
|
|
|
|
|
pSocket->Leave();
|
|
|
|
|
|
|
|
|
|
|
|
m_RecvQueue.erase(ii);
|
|
|
|
|
|
m_RecvSeqCnt += 8;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} while(lastcnt != m_RecvSeqCnt);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case 4 : case 5 :
|
|
|
|
|
|
// <09><><EFBFBD><EFBFBD> ť<><C5A5><EFBFBD><EFBFBD> ack<63><6B> <20><><EFBFBD>ϵǸ<CFB5> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>
|
|
|
|
|
|
#ifdef _FINAL_BUILD
|
|
|
|
|
|
if (_PACKET_ACKN(header->acknum) > 16) break;
|
|
|
|
|
|
#else
|
|
|
|
|
|
_ASSERT(_PACKET_ACKN(header->acknum) <= 16);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
pSocket->Enter();
|
|
|
|
|
|
if (RemoveQueue(_PACKET_TYPE(header->flags), (unsigned short *)&header[1], _PACKET_ACKN(header->acknum)) == false)
|
|
|
|
|
|
{ // ack <20><> <20><><EFBFBD><EFBFBD> <20>Դٴ<D4B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ѹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ι<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD>
|
|
|
|
|
|
// <09><> <20><> <20>ִ<EFBFBD>. RTO Ÿ<>̹<EFBFBD><CCB9><EFBFBD> <20>÷<EFBFBD><C3B7>ش<EFBFBD>. <20><>, 400<30><30> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (m_RTOTick < 450)
|
|
|
|
|
|
m_RTOTick += 15;
|
|
|
|
|
|
}
|
|
|
|
|
|
pSocket->Leave();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 6 :
|
|
|
|
|
|
//RELIABLEó<45><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>û <20>ؿ´<D8BF>. <20>Ҿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
#ifdef _FINAL_BUILD
|
|
|
|
|
|
if (_PACKET_ACKN(header->acknum) > 16) break;
|
|
|
|
|
|
#else
|
|
|
|
|
|
_ASSERT(_PACKET_ACKN(header->acknum) <= 16);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
pSocket->Enter();
|
|
|
|
|
|
ReSendQueue(_PACKET_TYPE(header->flags), (unsigned short *)&header[1], _PACKET_ACKN(header->acknum), pSocket);
|
|
|
|
|
|
pSocket->Leave();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3 : {
|
|
|
|
|
|
//// PING <20>̿<EFBFBD>, PONG <20>Ͽ<EFBFBD>
|
|
|
|
|
|
//_RELIABLE_UDP_HEADER ack;
|
|
|
|
|
|
//ack.combo = _PACKET_HEADER(6, 0);//_PACKET_PINGCNT(header->pingcnt));
|
|
|
|
|
|
//ack.crc = 0;
|
|
|
|
|
|
//ack.crc = GetCRC((unsigned char*)&ack, sizeof(ack));
|
|
|
|
|
|
//pSocket->SendTo(&ack, sizeof(ack), &m_TargetAddr);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case 7 :
|
|
|
|
|
|
pSocket->Enter();
|
|
|
|
|
|
pSocket->DisConnectPtr(this, true);
|
|
|
|
|
|
pSocket->Leave();
|
|
|
|
|
|
break;
|
|
|
|
|
|
default :
|
|
|
|
|
|
_ASSERT(0);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned char CRUDPConnect::GetCRC(const unsigned char * data, int len)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned int code = 0;
|
|
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
|
|
code += data[i];
|
|
|
|
|
|
return (0x78 - code + len);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPConnect::SendAck(int iFlags, int iAck, SOCKADDR_IN * pAddr, CRUDPSocketFrame * pSocket)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT(iFlags == 4 || iFlags == 5 || iFlags == 6);
|
|
|
|
|
|
_ASSERT((iAck&7) == 0);
|
|
|
|
|
|
_ASSERT(!memcmp(&m_TargetAddr, pAddr, sizeof(SOCKADDR_IN)));
|
|
|
|
|
|
int n = iFlags-4, i;
|
|
|
|
|
|
|
|
|
|
|
|
for(i=0; i < m_AckListCnt[n]; i++)
|
|
|
|
|
|
if (m_AckList[n][i] == iAck)
|
|
|
|
|
|
return ;
|
|
|
|
|
|
|
|
|
|
|
|
if (m_AckListCnt[n] >= 16)
|
|
|
|
|
|
FlushAck(pSocket);
|
|
|
|
|
|
|
|
|
|
|
|
m_AckList[n][m_AckListCnt[n]++] = iAck;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CRUDPConnect::ReSendQueue(unsigned short iType, unsigned short * iAckList, int iAckNum, CRUDPSocketFrame * pSocket)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::list <_PACKET_QUEUE*>::iterator ii;
|
|
|
|
|
|
for (ii = m_SendQueue.begin(); ii != m_SendQueue.end(); ii++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_PACKET_QUEUE * pq = (*ii);
|
|
|
|
|
|
for (int i = 0; i < iAckNum; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT((iAckList[i]&7) == 0);
|
|
|
|
|
|
//<2F><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>͵<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ°<D6B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ÿ<EFBFBD>ֿ̹<CCB9> <20>Ĵٴٴ<D9B4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|
|
|
|
|
if (pq->seq < iAckList[i])
|
|
|
|
|
|
{
|
|
|
|
|
|
pSocket->SendTo(pq->data, pq->len, &m_TargetAddr);
|
|
|
|
|
|
pq->tick = pSocket->GetCurTick(); //<2F>ʹ<EFBFBD> ª<><C2AA> <20>ð<EFBFBD><C3B0><EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʵ<EFBFBD><CAB5><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (pq->seq <= iAckList[i])
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CRUDPConnect::RemoveQueue(unsigned short iType, unsigned short * iAckList, int iAckNum)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::list <_PACKET_QUEUE*>::iterator ii;
|
|
|
|
|
|
int i , cnt = 0;
|
|
|
|
|
|
for (ii = m_SendQueue.begin(); ii != m_SendQueue.end() && cnt < iAckNum;)
|
|
|
|
|
|
{
|
|
|
|
|
|
_PACKET_QUEUE * pq = (*ii);
|
|
|
|
|
|
for (i = 0; i < iAckNum; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT((iAckList[i]&7) == 0);
|
|
|
|
|
|
if (pq->seq == iAckList[i] && pq->type == iType)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (i < iAckNum)
|
|
|
|
|
|
{
|
|
|
|
|
|
ReleaseQueue(pq);
|
|
|
|
|
|
m_SendQueue.erase(ii);
|
|
|
|
|
|
ii = m_SendQueue.begin();
|
|
|
|
|
|
cnt++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
ii++;
|
|
|
|
|
|
}
|
|
|
|
|
|
return cnt > 0 ? true : false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_PACKET_QUEUE * CRUDPConnect::CreateQueue(CRUDPSocketFrame *pSocket, void * buffer, int len, int type)
|
|
|
|
|
|
{
|
|
|
|
|
|
_PACKET_QUEUE * q;
|
|
|
|
|
|
int lv, i;
|
|
|
|
|
|
_ASSERT(len < 512 - sizeof(_PACKET_QUEUE));
|
|
|
|
|
|
lv = MemLevel(sizeof(_PACKET_QUEUE) + len) ;
|
|
|
|
|
|
static const int _size[] = { 32, 64, 128, 256, 512 };
|
|
|
|
|
|
if( lv >= _countof(_size) )
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
if( m_EmptyQueue[lv].empty() )
|
|
|
|
|
|
{
|
|
|
|
|
|
char * ptr = new char [1024];
|
|
|
|
|
|
if (ptr == NULL) return NULL;
|
|
|
|
|
|
m_AllocedQueue.push_back(ptr);
|
|
|
|
|
|
for(i=0; i<1024; i+=_size[lv])
|
|
|
|
|
|
m_EmptyQueue[lv].push_back((_PACKET_QUEUE*)(ptr + i));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_ASSERT( !m_EmptyQueue[lv].empty() );
|
|
|
|
|
|
q = m_EmptyQueue[lv].back();
|
|
|
|
|
|
m_EmptyQueue[lv].pop_back();
|
|
|
|
|
|
|
|
|
|
|
|
q->seq = _PACKET_SEQ(((_RELIABLE_UDP_HEADER*)buffer)->seq);
|
|
|
|
|
|
q->type = type;
|
|
|
|
|
|
q->len = (unsigned short) len;
|
|
|
|
|
|
q->origintick = q->tick = pSocket->GetCurTick();
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(q->data, buffer, len);
|
|
|
|
|
|
return q;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CRUDPConnect::ReleaseQueue(_PACKET_QUEUE * pQueue)
|
|
|
|
|
|
{
|
|
|
|
|
|
int lv = MemLevel(sizeof(_PACKET_QUEUE) + pQueue->len) ;
|
|
|
|
|
|
m_EmptyQueue[lv].push_back(pQueue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CRUDPConnect::MemLevel(int size)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERT(size < 512);
|
|
|
|
|
|
|
|
|
|
|
|
if (size <= 64)
|
|
|
|
|
|
return size <= 32 ? 0 : 1;
|
|
|
|
|
|
if (size <= 256)
|
|
|
|
|
|
return size <= 128 ? 2 : 3;
|
|
|
|
|
|
return size <= 512 ? 4 : 5;
|
|
|
|
|
|
}
|