| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- #include "StdAfx.h"
- #include "ClientContainer.h"
- #include "NetClient.h"
- CClientContainer::CClientContainer(void)
- {
- }
- CClientContainer::~CClientContainer(void)
- {
- release();
- }
- /*****************************************************************
- **【函数名称】 __add2List
- **【函数功能】 客户端添加到指定队列中
- **【参数】
- **【返回值】
- ****************************************************************/
- void CClientContainer::__add2List( CNetClient* a_pClient, ListClient& a_list, CCriticalSection* a_pCs )
- {
- CSingleLock Lock(a_pCs);
- Lock.Lock();
- a_list.AddTail(a_pClient);
- }
- /*****************************************************************
- **【函数名称】 __onConnFailedProc
- **【函数功能】 客户端连接断开/失败的后续处理
- **【参数】 a_pClient: 连接断开/失败的客户端
- **【返回值】
- ****************************************************************/
- void CClientContainer::__onConnFailedProc( CNetClient* a_pClient )
- {
- // 连接类型处理不同
- if(a_pClient->linkType() == PDU_LINK_TYPE_CLIENT)
- {
- __add2List(a_pClient, m_listConnecting, &m_CS4Connecting);
- }
- else
- {
- __deleteClient(a_pClient);
- } // end if
- }
- /*****************************************************************
- **【函数名称】 __deleteClient
- **【函数功能】 删除指定的连接
- **【参数】
- **【返回值】
- ****************************************************************/
- void CClientContainer::__deleteClient( CNetClient* a_pClient )
- {
- ASSERT(a_pClient != NULL);
- a_pClient->drop();
- __add2List(a_pClient, m_ListDeleted, &m_Cs4Deleted);
- }
- /*****************************************************************
- **【函数名称】 __removeClient
- **【函数功能】 从LIST中移出指定的连接(不是删除)
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CClientContainer::__removeClient( CNetClient* a_pClient, ListClient& a_list, CCriticalSection* a_pCs )
- {
- ASSERT(a_pClient != NULL);
- CSingleLock Locker(a_pCs);
- Locker.Lock();
- POSITION Pos = a_list.Find(a_pClient);
- if(Pos != NULL)
- {
- a_list.RemoveAt(Pos);
- return true;
- }
- else
- return false;
- }
- /*****************************************************************
- **【函数名称】 __lookup
- **【函数功能】 从LIST中查找指定的连接
- **【参数】 a_nFarType 对端设备类型
- a_nFarId 对端设备ID
- **【返回值】
- ****************************************************************/
- CNetClient* CClientContainer::__lookup( PDU_DEV_TYPE a_nFarType, int a_nFarId, ListClient& a_list, CCriticalSection* a_pCs )
- {
- CSingleLock Locker(a_pCs);
- Locker.Lock();
- POSITION pos = a_list.GetHeadPosition();
- PDU_DEV_TYPE nType = PDU_DEV_TYPE_UNKNOWN;
- int nId = -1;
- while(pos != NULL)
- {
- CNetClient* pClient = a_list.GetNext(pos);
- ASSERT(pClient != NULL);
-
- pClient->getFarDevInfo(nType, nId);
- if(nType == a_nFarType && nId == a_nFarId)
- return pClient;
- } // end while
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 __lookup
- **【函数功能】 从LIST中查找指定的连接
- **【参数】 a_hSocket SOCKET句柄
- **【返回值】
- ****************************************************************/
- CNetClient* CClientContainer::__lookup( SOCKET a_hSocket, ListClient& a_list, CCriticalSection* a_pCs )
- {
- CSingleLock Locker(a_pCs);
- Locker.Lock();
- POSITION pos = a_list.GetHeadPosition();
- while(pos != NULL)
- {
- CNetClient* pClient = a_list.GetNext(pos);
- ASSERT(pClient != NULL);
- if(pClient->assoSocket() == a_hSocket)
- return pClient;
- } // end while
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 __lookup
- **【函数功能】 从LIST中查找指定的连接
- **【参数】
- **【返回值】
- ****************************************************************/
- CNetClient* CClientContainer::__lookup( CNetClient* a_pClient, ListClient& a_list, CCriticalSection* a_pCs )
- {
- CSingleLock Locker(a_pCs);
- Locker.Lock();
- POSITION Pos = a_list.Find(a_pClient);
- if(Pos != NULL)
- return a_pClient;
- else
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 __lookup4Delete
- **【函数功能】 从LIST中查找指定的连接并删除
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CClientContainer::__lookup4Delete( PDU_DEV_TYPE a_nFarType, int a_nFarId, ListClient& a_list, CCriticalSection* a_pCs )
- {
- CSingleLock Locker(a_pCs);
- Locker.Lock();
- PDU_DEV_TYPE nType = PDU_DEV_TYPE_UNKNOWN;
- int nId = -1;
- POSITION pos = a_list.GetHeadPosition();
- while(pos != NULL)
- {
- POSITION posPrev = pos;
- CNetClient* pClient = a_list.GetNext(pos);
- ASSERT(pClient != NULL);
- pClient->getFarDevInfo(nType, nId);
- if(nType == a_nFarType && nId == a_nFarId)
- {
- a_list.RemoveAt(posPrev);
- // 删除
- __deleteClient(pClient);
- return true;
- }
- } // end while
- return false;
- }
- /*****************************************************************
- **【函数名称】 __lookup4Delete
- **【函数功能】 从LIST中查找指定的连接并删除
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CClientContainer::__lookup4Delete( SOCKET a_hSocket, ListClient& a_list, CCriticalSection* a_pCs )
- {
- CSingleLock Locker(a_pCs);
- Locker.Lock();
- POSITION pos = a_list.GetHeadPosition();
- while(pos != NULL)
- {
- POSITION posPrev = pos;
- CNetClient* pClient = a_list.GetNext(pos);
- ASSERT(pClient != NULL);
- if(pClient->assoSocket() == a_hSocket)
- {
- a_list.RemoveAt(posPrev);
- // 删除
- __deleteClient(pClient);;
- return true;
- }
- } // end while
- return false;
- }
- /*****************************************************************
- **【函数名称】 insertSocket
- **【函数功能】 添加一个新的连接
- **【参数】 a_pSocket 要添加的连接
- **【返回值】
- ****************************************************************/
- void CClientContainer::insertClient( CNetClient* a_pClient )
- {
- __add2List(a_pClient, m_listConnecting, &m_CS4Connecting);
- }
- /*****************************************************************
- **【函数名称】 removeClient
- **【函数功能】 删除一个连接
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CClientContainer::removeClient( PDU_DEV_TYPE a_nFarType, int a_nFarId )
- {
- // 注意此处的查找顺序:会影响到座席的重复签入控制
- // 已注册的客户端
- if(__lookup4Delete(a_nFarType, a_nFarId, m_listRegisted, &m_CS4Registed))
- return true;
- // 已连接的客户端
- if(__lookup4Delete(a_nFarType, a_nFarId, m_listConnected, &m_CS4Connected))
- return true;
- // 正在连接的客户端
- if(__lookup4Delete(a_nFarType, a_nFarId, m_listConnecting, &m_CS4Connecting))
- return true;
- return false;
- }
- /*****************************************************************
- **【函数名称】 removeClient
- **【函数功能】 删除一个连接
- **【参数】
- **【返回值】
- ****************************************************************/
- bool CClientContainer::removeClient( SOCKET a_hSocket )
- {
- // 已注册的客户端
- if(__lookup4Delete(a_hSocket, m_listRegisted, &m_CS4Registed))
- return true;
- // 已连接的客户端
- if(__lookup4Delete(a_hSocket, m_listConnected, &m_CS4Connected))
- return true;
- // 正在连接的客户端
- if(__lookup4Delete(a_hSocket, m_listConnecting, &m_CS4Connecting))
- return true;
- return false;
- }
- /*****************************************************************
- **【函数名称】 getClient
- **【函数功能】 根据对端设备类型、ID查找指定连接
- **【参数】 a_nFarType 对端设备类型
- a_nFarId 对端设备ID
- **【返回值】
- ****************************************************************/
- CNetClient* CClientContainer::getClient( PDU_DEV_TYPE a_nFarType, int a_nFarId )
- {
- // 已注册的SOCKET
- CNetClient* pCLient = __lookup(a_nFarType, a_nFarId, m_listRegisted, &m_CS4Registed);
- if(pCLient != NULL) return pCLient;
- // 已连接的SOCKET
- pCLient = __lookup(a_nFarType, a_nFarId, m_listConnected, &m_CS4Connected);
- if(pCLient != NULL) return pCLient;
- // 正在连接的SOCKET
- pCLient = __lookup(a_nFarType, a_nFarId, m_listConnecting, &m_CS4Connecting);
- if(pCLient != NULL) return pCLient;
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getClient
- **【函数功能】 根据SOCKET句柄查找指定连接
- **【参数】 a_hSocket SOCKET句柄
- **【返回值】
- ****************************************************************/
- CNetClient* CClientContainer::getClient( SOCKET a_hSocket )
- {
- CNetClient* pClient = NULL;
- pClient = __lookup(a_hSocket, m_listConnecting, &m_CS4Connecting);
- if(pClient != NULL) return pClient;
- pClient = __lookup(a_hSocket, m_listConnected, &m_CS4Connected);
- if(pClient != NULL) return pClient;
- pClient = __lookup(a_hSocket, m_listRegisted, &m_CS4Registed);
- if(pClient != NULL) return pClient;
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getClient
- **【函数功能】 根据SOCKET句柄查找指定连接
- **【参数】
- **【返回值】
- ****************************************************************/
- CNetClient* CClientContainer::getClient( CNetClient* a_pClient )
- {
- CNetClient* pClient = NULL;
- pClient = __lookup(a_pClient, m_listRegisted, &m_CS4Registed);
- if(pClient != NULL) return pClient;
- pClient = __lookup(a_pClient, m_listConnecting, &m_CS4Connecting);
- if(pClient != NULL) return pClient;
- pClient = __lookup(a_pClient, m_listConnected, &m_CS4Connected);
- if(pClient != NULL) return pClient;
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 send2All
- **【函数功能】 向所有注册过的客户端发送PDU
- **【参数】
- **【返回值】
- ****************************************************************/
- void CClientContainer::send2All( CPduEntity* a_pPdu )
- {
- ASSERT(a_pPdu != NULL);
- CSingleLock Locker(&m_CS4Registed);
- Locker.Lock();
- POSITION pos = m_listRegisted.GetHeadPosition();
- while(pos != NULL)
- {
- CNetClient* pClient = m_listRegisted.GetNext(pos);
- ASSERT(pClient != NULL);
- pClient->sendPdu(a_pPdu);
- } // end while
- }
- /*****************************************************************
- **【函数名称】 release
- **【函数功能】 释放资源
- **【参数】
- **【返回值】
- ****************************************************************/
- void CClientContainer::release( void )
- {
- while(m_ListDeleted.GetCount() > 0)
- {
- delete m_ListDeleted.RemoveHead();
- }
- while(m_listConnecting.GetCount() > 0)
- {
- delete m_listConnecting.RemoveHead();
- }
- while(m_listConnected.GetCount() > 0)
- {
- delete m_listConnected.RemoveHead();
- }
- while(m_listRegisted.GetCount() > 0)
- {
- delete m_listRegisted.RemoveHead();
- }
- }
- /*****************************************************************
- **【函数名称】 clearClientDeleted
- **【函数功能】 清理缓存的已删除客户端
- **【参数】
- **【返回值】
- ****************************************************************/
- void CClientContainer::clearClientDeleted( void )
- {
- m_Cs4Deleted.Lock();
- while(m_ListDeleted.GetCount() > 0)
- delete m_ListDeleted.RemoveHead();
- m_Cs4Deleted.Unlock();
- }
- /*****************************************************************
- **【函数名称】 onConnEstablished
- **【函数功能】 连接建立事件处理
- **【参数】 a_pClient 已建立连接的客户端
- **【返回值】
- ****************************************************************/
- PDU_LINK_STATE CClientContainer::onConnEstablished( CNetClient* a_pClient )
- {
- PDU_LINK_STATE nLinkState = PDU_LINK_STATE_UNKNOWN; // 未知
- if(a_pClient->linkType() == PDU_LINK_TYPE_SERVER) // SERVER端
- {
- __add2List(a_pClient, m_listConnected, &m_CS4Connected);
- nLinkState = PDU_LINK_STATE_ACCEPTED;
- }
- else // CLIENT端
- {
- __removeClient(a_pClient, m_listConnecting, &m_CS4Connecting);
- __add2List(a_pClient, m_listConnected, &m_CS4Connected);
- nLinkState = PDU_LINK_STATE_SUCCESSED;
- } // end if
- return nLinkState;
- }
- /*****************************************************************
- **【函数名称】 onConnFailed
- **【函数功能】 连接失败/断开事件处理
- **【参数】 a_pClient 已建立连接的客户端
- **【返回值】
- ****************************************************************/
- PDU_LINK_STATE CClientContainer::onConnFailed( CNetClient* a_pClient )
- {
- PDU_LINK_STATE nLinkState = PDU_LINK_STATE_UNKNOWN; // 未知
- if(__removeClient(a_pClient, m_listRegisted, &m_CS4Registed)) // 正在进行通讯
- {
- nLinkState = PDU_LINK_STATE_DISCONNECTED;
- __onConnFailedProc(a_pClient); // 后续处理
- }
- else if(__removeClient(a_pClient, m_listConnected, &m_CS4Connected)) // 未握手
- {
- nLinkState = PDU_LINK_STATE_DISCONNECTED;
- __onConnFailedProc(a_pClient); // 后续处理
- }
- else if(__lookup(a_pClient->assoSocket(), m_listConnecting, &m_CS4Connecting) != NULL) // 初次连接/重连
- {
- nLinkState = PDU_LINK_STATE_FAILED;
- }
- else
- {
- nLinkState = PDU_LINK_STATE_FAILED;
- } // end if
- return nLinkState;
- }
- /*****************************************************************
- **【函数名称】 onConnRegistOK
- **【函数功能】 连接注册成功事件处理
- **【参数】 a_pClient 已注册成功的客户端
- **【返回值】
- ****************************************************************/
- PDU_LINK_STATE CClientContainer::onConnRegistOK( CNetClient* a_pClient )
- {
- __removeClient(a_pClient, m_listConnected, &m_CS4Connected);
- __add2List(a_pClient, m_listRegisted, &m_CS4Registed);
- return PDU_LINK_STATE_REG_OK;
- }
- /*****************************************************************
- **【函数名称】 onConnRegistFailed
- **【函数功能】 连接注册失败事件处理
- **【参数】 a_pClient 已注册失败的客户端
- **【返回值】
- ****************************************************************/
- PDU_LINK_STATE CClientContainer::onConnRegistFailed( CNetClient* a_pClient )
- {
- return PDU_LINK_STATE_REG_FAILED;
- }
|