f-stack/app/micro_thread/mt_net.h

719 lines
17 KiB
C
Raw Normal View History

2017-04-21 13:43:26 +03:00
/**
* Tencent is pleased to support the open source community by making MSEC available.
*
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the GNU General Public License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* https://opensource.org/licenses/GPL-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
/**
* @file mt_net.h
* @info ΢<EFBFBD>̷߳<EFBFBD>װ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD><EFBFBD><EFBFBD>
**/
#ifndef __MT_NET_H__
#define __MT_NET_H__
#include "micro_thread.h"
#include "hash_list.h"
#include "mt_api.h"
#include "mt_cache.h"
#include "mt_net_api.h"
namespace NS_MICRO_THREAD {
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD><EFBFBD>
*/
enum MT_CONN_TYPE
{
TYPE_CONN_UNKNOWN = 0,
TYPE_CONN_SHORT = 0x1, ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, һ<>ν<EFBFBD><CEBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD>
TYPE_CONN_POOL = 0x2, ///< <20><><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>ÿ<EFBFBD><C3BF>ʹ<EFBFBD>ú<EFBFBD>, <20>ɻ<EFBFBD><C9BB><EFBFBD><EFBFBD>ظ<EFBFBD>ʹ<EFBFBD><CAB9>
TYPE_CONN_SESSION = 0x4, ///< <20><><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>session id <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TYPE_CONN_SENDONLY = 0x8, ///< ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
/******************************************************************************/
/* <20>ڲ<EFBFBD>ʵ<EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD> */
/******************************************************************************/
class CSockLink;
/**
* @brief <EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>յĶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>
* @info List<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tailq, Type <EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>reset<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, releasetime, linkentry<EFBFBD>ֶ<EFBFBD>
*/
template <typename List, typename Type>
class CRecyclePool
{
public:
// <20><><EFBFBD><EFBFBD><ECBAAF>, Ĭ<><C4AC>60s<30><73>ʱ
CRecyclePool() {
_expired = 60 * 1000;
_count = 0;
TAILQ_INIT(&_free_list);
};
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>
~CRecyclePool() {
Type* item = NULL;
Type* tmp = NULL;
TAILQ_FOREACH_SAFE(item, &_free_list, _link_entry, tmp)
{
TAILQ_REMOVE(&_free_list, item, _link_entry);
delete item;
}
_count = 0;
};
// <20><><EFBFBD>û<EFBFBD><C3BB>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Type* AllocItem() {
Type* item = TAILQ_FIRST(&_free_list);
if (item != NULL)
{
TAILQ_REMOVE(&_free_list, item, _link_entry);
_count--;
return item;
}
item = new Type();
if (NULL == item)
{
return NULL;
}
return item;
};
// <20>ͷŹ<CDB7><C5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void FreeItem(Type* obj) {
//obj->Reset();
TAILQ_INSERT_TAIL(&_free_list, obj, _link_entry);
obj->_release_time = mt_time_ms();
_count++;
};
// <20><><EFBFBD>վ<EFBFBD><D5BE><EFBFBD>
void RecycleItem(uint64_t now) {
Type* item = NULL;
Type* tmp = NULL;
TAILQ_FOREACH_SAFE(item, &_free_list, _link_entry, tmp)
{
if ((now - item->_release_time) < _expired) {
break;
}
TAILQ_REMOVE(&_free_list, item, _link_entry);
delete item;
_count--;
}
};
// <20><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>ij<EFBFBD>ʱʱ<CAB1><CAB1>
void SetExpiredTime(uint64_t expired) {
_expired = expired;
};
private:
List _free_list; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint64_t _expired; ///< <20><>ʱʱ<CAB1><CAB1>
uint32_t _count; ///< Ԫ<>ؼ<EFBFBD><D8BC><EFBFBD>
};
/**
* @brief ÿ<EFBFBD><EFBFBD>IO<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class CNetHandler : public HashKey
{
public:
// <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>
enum {
STATE_IN_SESSION = 0x1,
STATE_IN_CONNECT = 0x2,
STATE_IN_SEND = 0x4,
STATE_IN_RECV = 0x8,
STATE_IN_IDLE = 0x10,
};
/**
* @brief <EFBFBD>ڵ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>hash<EFBFBD>, <EFBFBD><EFBFBD>ȡkey<EFBFBD><EFBFBD>hashֵ
* @return <EFBFBD>ڵ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>hashֵ
*/
virtual uint32_t HashValue();
/**
* @brief <EFBFBD>ڵ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>cmp<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ͬһͰID<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>key<EFBFBD>Ƚ<EFBFBD>
* @return <EFBFBD>ڵ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>hashֵ
*/
virtual int HashCmp(HashKey* rhs);
// ͬ<><CDAC><EFBFBD>շ<EFBFBD><D5B7>ӿ<EFBFBD>
int32_t SendRecv(void* data, uint32_t len, uint32_t timeout);
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>buff<66><66>Ϣ, <20><>Ч<EFBFBD><D0A7>ֱ<EFBFBD><D6B1>helper<65><72><EFBFBD><EFBFBD>
void* GetRspBuff() {
if (_rsp_buff != NULL) {
return _rsp_buff->data;
} else {
return NULL;
}
};
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>buff<66><66>Ϣ, <20><>Ч<EFBFBD><D0A7>ֱ<EFBFBD><D6B1>helper<65><72><EFBFBD><EFBFBD>
uint32_t GetRspLen() {
if (_rsp_buff != NULL) {
return _rsp_buff->data_len;
} else {
return 0;
}
};
// <20><><EFBFBD><EFBFBD>rsp<73><70>Ϣ
void SetRespBuff(TSkBuffer* buff) {
if (_rsp_buff != NULL) {
delete_sk_buffer(_rsp_buff);
_rsp_buff = NULL;
}
_rsp_buff = buff;
};
// <20><><EFBFBD><EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, Ĭ<><C4AC>UDP
void SetProtoType(MT_PROTO_TYPE type) {
_proto_type = type;
};
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, Ĭ<>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD>
void SetConnType(MT_CONN_TYPE type) {
_conn_type = type;
};
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>IP<49><50>ַ
void SetDestAddress(struct sockaddr_in* dst) {
if (dst != NULL) {
memcpy(&_dest_ipv4, dst, sizeof(*dst));
}
};
// <20><><EFBFBD><EFBFBD>session<6F><6E><EFBFBD><EFBFBD>session id<69><64>Ϣ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0
void SetSessionId(uint64_t sid) {
_session_id = sid;
};
// <20><><EFBFBD><EFBFBD>session<6F><6E><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
void SetSessionCallback(CHECK_SESSION_CALLBACK function) {
_callback = function;
};
// <20><>ȡ<EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
CHECK_SESSION_CALLBACK GetSessionCallback() {
return _callback;
};
public:
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
void Link(CSockLink* conn);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
void Unlink();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>Ϣ
int32_t CheckParams();
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>, ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>ӵĶ<D3B5><C4B6><EFBFBD><EFBFBD><EFBFBD>
int32_t GetConnLink();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>Ϣ
int32_t WaitConnect(uint64_t timeout);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>Ϣ
int32_t WaitSend(uint64_t timeout);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>Ϣ
int32_t WaitRecv(uint64_t timeout);
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵȴ<DAB5><C8B4><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
void SwitchToConn();
// <20>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD>
void SwitchToSend();
// <20>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ն<EFBFBD><D5B6><EFBFBD>
void SwitchToRecv();
// <20>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
void SwitchToIdle();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>
void DetachConn();
// ע<><D7A2>session<6F><6E><EFBFBD><EFBFBD>
bool RegistSession();
// ȡ<><C8A1>ע<EFBFBD><D7A2>session
void UnRegistSession();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD>󳤶<EFBFBD>
uint32_t SkipSendPos(uint32_t len);
// <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD>
void SetErrNo(int32_t err) {
_err_no = err;
};
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD>Ϣ
MicroThread* GetThread() {
return _thread;
};
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
void GetSendData(void*& data, uint32_t& len) {
data = _req_data;
len = _req_len;
};
// <20><><EFBFBD>ýӿ<C3BD>
void Reset();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CNetHandler();
~CNetHandler();
// <20><><EFBFBD>п<EFBFBD><D0BF>ݷ<EFBFBD><DDB7>ʵĺ궨<C4BA><EAB6A8>
TAILQ_ENTRY(CNetHandler) _link_entry;
uint64_t _release_time;
protected:
MicroThread* _thread; ///< <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MT_PROTO_TYPE _proto_type; ///< Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MT_CONN_TYPE _conn_type; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
struct sockaddr_in _dest_ipv4; ///< ipv4Ŀ<34>ĵ<EFBFBD>ַ
uint64_t _session_id; ///< <20>ỰID
CHECK_SESSION_CALLBACK _callback; ///< <20><EFBFBD><E1BBB0>ȡ<EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
uint32_t _state_flags; ///< <20>ڲ<EFBFBD>״̬<D7B4>ֶ<EFBFBD>
int32_t _err_no; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
void* _conn_ptr; ///< socket <20><>·ָ<C2B7><D6B8>
uint32_t _send_pos; ///< <20>ѷ<EFBFBD><D1B7>͵<EFBFBD>posλ<73><CEBB>
uint32_t _req_len; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void* _req_data; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
TSkBuffer* _rsp_buff; ///< Ӧ<><D3A6>buff<66><66>Ϣ
};
typedef TAILQ_HEAD(__NetHandlerList, CNetHandler) TNetItemList; ///< <20><>Ч<EFBFBD><D0A7>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
typedef CRecyclePool<TNetItemList, CNetHandler> TNetItemPool; ///< <20><>ʱ<EFBFBD><CAB1><EFBFBD>յĶ<D5B5><C4B6><EFBFBD><EFBFBD><EFBFBD>
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class CSockLink : public KqueuerObj
{
public:
// <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>
enum {
LINK_CONNECTING = 0x1,
LINK_CONNECTED = 0x2,
};
// ״̬<D7B4><CCAC><EFBFBD>ж<EFBFBD><D0B6><EFBFBD>
enum {
LINK_IDLE_LIST = 1,
LINK_CONN_LIST = 2,
LINK_SEND_LIST = 3,
LINK_RECV_LIST = 4,
};
// <20><><EFBFBD><EFBFBD><EFBFBD>򴴽<EFBFBD>socket<65><74><EFBFBD><EFBFBD>
int32_t CreateSock();
// <20>ر<EFBFBD><D8B1><EFBFBD>·<EFBFBD>ľ<EFBFBD><C4BE><EFBFBD>
void Close();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD>
bool Connect();
bool Connected() {
return (_state & LINK_CONNECTED);
}
// <20><EFBFBD><ECB3A3>ֹ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void Destroy();
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TNetItemList* GetItemList(int32_t type);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
void AppendToList(int32_t type, CNetHandler* item);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
void RemoveFromList(int32_t type, CNetHandler* item);
// <20><>ȡĿ<C8A1><C4BF>ip<69><70>Ϣ
struct sockaddr_in* GetDestAddr(struct sockaddr_in* addr);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD>
int32_t SendData(void* data, uint32_t len);
// udp<64><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int32_t SendCacheUdp(void* data, uint32_t len);
// tcp<63><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int32_t SendCacheTcp(void* data, uint32_t len);
// <20><><EFBFBD>Խ<EFBFBD><D4BD>ո<EFBFBD><D5B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD>ʱbuff
void ExtendRecvRsp();
// <20><><EFBFBD>ݷַ<DDB7><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int32_t RecvDispath();
// <20><><EFBFBD>߻ص<DFBB><D8B5><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>ȴ<EFBFBD><C8B4>Ŷӵȴ<D3B5><C8B4>л<EFBFBD>ȡ, <20><><EFBFBD>ݴӸ<DDB4><D3B8>ڵ<EFBFBD><DAB5><EFBFBD>ȡ
CHECK_SESSION_CALLBACK GetSessionCallback();
// TCP<43><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
int32_t DispathTcp();
// UDP<44><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
int32_t DispathUdp();
// <20><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD>sessionid<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>session<6F><6E>Ϣ
CNetHandler* FindSession(uint64_t sid);
/**
* @brief <EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int InputNotify();
/**
* @brief <EFBFBD><EFBFBD>д<EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int OutputNotify();
/**
* @brief <EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>
* @return <EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD>ֵ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual int HangupNotify();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CSockLink();
~CSockLink();
// <20><><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>߼<EFBFBD>
void Reset();
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
void NotifyThread(CNetHandler* item, int32_t result);
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
void NotifyAll(int32_t result);
// <20><><EFBFBD><EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>buff<66>ص<EFBFBD>ָ<EFBFBD><D6B8>
void SetProtoType(MT_PROTO_TYPE type);
// <20><><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>Ϣ
void SetParentsPtr(void* ptr) {
_parents = ptr;
};
// <20><>ȡ<EFBFBD>ϼ<EFBFBD><CFBC>ڵ<EFBFBD>ָ<EFBFBD><D6B8>
void* GetParentsPtr() {
return _parents;
};
// <20><>ȡ<EFBFBD>ϴεķ<CEB5><C4B7><EFBFBD>ʱ<EFBFBD><CAB1>
uint64_t GetLastAccess() {
return _last_access;
};
public:
// <20><><EFBFBD>п<EFBFBD><D0BF>ݷ<EFBFBD><DDB7>ʵĺ궨<C4BA><EAB6A8>
TAILQ_ENTRY(CSockLink) _link_entry;
uint64_t _release_time;
private:
TNetItemList _wait_connect;
TNetItemList _wait_send;
TNetItemList _wait_recv;
TNetItemList _idle_list;
MT_PROTO_TYPE _proto_type;
int32_t _errno;
uint32_t _state;
uint64_t _last_access;
TRWCache _recv_cache;
TSkBuffer* _rsp_buff;
void* _parents;
};
typedef TAILQ_HEAD(__SocklinkList, CSockLink) TLinkList; ///< <20><>Ч<EFBFBD><D0A7>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
typedef CRecyclePool<TLinkList, CSockLink> TLinkPool; ///< <20><>ʱ<EFBFBD><CAB1><EFBFBD>յĶ<D5B5><C4B6><EFBFBD><EFBFBD><EFBFBD>
class CDestLinks : public CTimerNotify, public HashKey
{
public:
// <20><><EFBFBD><EFBFBD><ECBAAF>
CDestLinks();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
~CDestLinks();
// <20><><EFBFBD>ø<EFBFBD><C3B8>õĽӿں<D3BF><DABA><EFBFBD>
void Reset();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
void StartTimer();
// <20><>ȡһ<C8A1><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>link, <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ѯ
CSockLink* GetSockLink();
// <20>ͷ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>link
void FreeSockLink(CSockLink* sock);
// <20><>ȡЭ<C8A1><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MT_PROTO_TYPE GetProtoType() {
return _proto_type;
};
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MT_CONN_TYPE GetConnType() {
return _conn_type;
};
// <20><><EFBFBD>ùؼ<C3B9><D8BC><EFBFBD>Ϣ
void SetKeyInfo(uint32_t ipv4, uint16_t port, MT_PROTO_TYPE proto, MT_CONN_TYPE conn) {
_addr_ipv4 = ipv4;
_net_port = port;
_proto_type = proto;
_conn_type = conn;
};
// <20><><EFBFBD><EFBFBD>KEY<45><59>Ϣ
void CopyKeyInfo(CDestLinks* key) {
_addr_ipv4 = key->_addr_ipv4;
_net_port = key->_net_port;
_proto_type = key->_proto_type;
_conn_type = key->_conn_type;
};
// <20><>ȡIP port<72><74>Ϣ
void GetDestIP(uint32_t& ip, uint16_t& port) {
ip = _addr_ipv4;
port = _net_port;
};
/**
* @brief <EFBFBD><EFBFBD>ʱ֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void timer_notify();
/**
* @brief <EFBFBD>ڵ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>hash<EFBFBD>, <EFBFBD><EFBFBD>ȡkey<EFBFBD><EFBFBD>hashֵ
* @return <EFBFBD>ڵ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>hashֵ
*/
virtual uint32_t HashValue() {
return _addr_ipv4 ^ (((uint32_t)_net_port << 16) | (_proto_type << 8) | _conn_type);
};
/**
* @brief <EFBFBD>ڵ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>cmp<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ͬһͰID<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>key<EFBFBD>Ƚ<EFBFBD>
* @return <EFBFBD>ڵ<EFBFBD>Ԫ<EFBFBD>ص<EFBFBD>hashֵ
*/
virtual int HashCmp(HashKey* rhs) {
CDestLinks* data = (CDestLinks*)(rhs);
if (!data) {
return -1;
}
if (this->_addr_ipv4 != data->_addr_ipv4) {
return (this->_addr_ipv4 > data->_addr_ipv4) ? 1 : -1;
}
if (this->_net_port != data->_net_port) {
return (this->_net_port > data->_net_port) ? 1 : -1;
}
if (this->_proto_type != data->_proto_type) {
return (this->_proto_type > data->_proto_type) ? 1 : -1;
}
if (this->_conn_type != data->_conn_type) {
return (this->_conn_type > data->_conn_type) ? 1 : -1;
}
return 0;
};
// <20><><EFBFBD><EFBFBD>session<6F><6E><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
void SetDefaultCallback(CHECK_SESSION_CALLBACK function) {
_dflt_callback = function;
};
// <20><>ȡ<EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
CHECK_SESSION_CALLBACK GetDefaultCallback() {
return _dflt_callback;
};
// <20><><EFBFBD>п<EFBFBD><D0BF>ݷ<EFBFBD><DDB7>ʵĺ궨<C4BA><EAB6A8>
TAILQ_ENTRY(CDestLinks) _link_entry;
uint64_t _release_time;
private:
uint32_t _timeout; ///< idle<6C>ij<EFBFBD>ʱʱ<CAB1><CAB1>
uint32_t _addr_ipv4; ///< ip<69><70>ַ
uint16_t _net_port; ///< port <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MT_PROTO_TYPE _proto_type; ///< Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MT_CONN_TYPE _conn_type; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint32_t _max_links; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint32_t _curr_link; ///< <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TLinkList _sock_list; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CHECK_SESSION_CALLBACK _dflt_callback; ///< Ĭ<>ϵ<EFBFBD>check<63><6B><EFBFBD><EFBFBD>
};
typedef TAILQ_HEAD(__DestlinkList, CDestLinks) TDestList; ///< <20><>Ч<EFBFBD><D0A7>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
typedef CRecyclePool<TDestList, CDestLinks> TDestPool; ///< <20><>ʱ<EFBFBD><CAB1><EFBFBD>յĶ<D5B5><C4B6><EFBFBD><EFBFBD><EFBFBD>
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>
*/
class CNetMgr
{
public:
/**
* @brief <EFBFBD><EFBFBD>Ϣbuff<EFBFBD><EFBFBD>ȫ<EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
* @return ȫ<EFBFBD>־<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
*/
static CNetMgr* Instance (void);
/**
* @brief <EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
*/
static void Destroy(void);
// <20><>ѯ<EFBFBD>Ƿ<EFBFBD><C7B7>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB>sid<69>Ķ<EFBFBD><C4B6><EFBFBD>
CNetHandler* FindNetItem(CNetHandler* key);
// ע<><D7A2>һ<EFBFBD><D2BB>item, <20>Ȳ<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>֤<EFBFBD>޳<EFBFBD>ͻ
void InsertNetItem(CNetHandler* item);
// <20>Ƴ<EFBFBD>һ<EFBFBD><D2BB>item<65><6D><EFBFBD><EFBFBD>
void RemoveNetItem(CNetHandler* item);
// <20><>ѯ<EFBFBD>򴴽<EFBFBD>һ<EFBFBD><D2BB>Ŀ<EFBFBD><C4BF>ip<69><70>links<6B>ڵ<EFBFBD>
CDestLinks* FindCreateDest(CDestLinks* key);
// ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>·<EFBFBD><C2B7>Ϣ
void DeleteDestLink(CDestLinks* dst);
// <20><>ѯ<EFBFBD>Ƿ<EFBFBD><C7B7>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB>sid<69>Ķ<EFBFBD><C4B6><EFBFBD>
CDestLinks* FindDestLink(CDestLinks* key);
// ע<><D7A2>һ<EFBFBD><D2BB>item, <20>Ȳ<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>֤<EFBFBD>޳<EFBFBD>ͻ
void InsertDestLink(CDestLinks* item);
// <20>Ƴ<EFBFBD>һ<EFBFBD><D2BB>item<65><6D><EFBFBD><EFBFBD>
void RemoveDestLink(CDestLinks* item);
/**
* @brief <EFBFBD><EFBFBD>Ϣbuff<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
~CNetMgr();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>Ϣ
*/
void RecycleObjs(uint64_t now);
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CNetHandler* AllocNetItem() {
return _net_item_pool.AllocItem();
};
// <20>ͷ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void FreeNetItem(CNetHandler* item) {
return _net_item_pool.FreeItem(item);
};
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>SOCK<43><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·
CSockLink* AllocSockLink() {
return _sock_link_pool.AllocItem();
};
// <20>ͷ<EFBFBD>һ<EFBFBD><D2BB>SOCK<43><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·
void FreeSockLink(CSockLink* item) {
return _sock_link_pool.FreeItem(item);
};
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>SOCK<43><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·
CDestLinks* AllocDestLink() {
return _dest_ip_pool.AllocItem();
};
// <20>ͷ<EFBFBD>һ<EFBFBD><D2BB>SOCK<43><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·
void FreeDestLink(CDestLinks* item) {
return _dest_ip_pool.FreeItem(item);
};
// <20><>ȡudp<64><70>buff<66><66><EFBFBD><EFBFBD>Ϣ
TSkBuffMng* GetSkBuffMng(MT_PROTO_TYPE type) {
if (type == NET_PROTO_TCP) {
return &_tcp_pool;
} else {
return &_udp_pool;
}
};
private:
/**
* @brief <EFBFBD><EFBFBD>Ϣbuff<EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
CNetMgr();
static CNetMgr * _instance; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
HashList* _ip_hash; ///< Ŀ<>ĵ<EFBFBD>ַhash
HashList* _session_hash; ///< session id<69><64>hash
TSkBuffMng _udp_pool; ///< udp pool, 64K
TSkBuffMng _tcp_pool; ///< tcp pool, 4K
TDestPool _dest_ip_pool; ///< Ŀ<><C4BF>ip<69><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TLinkPool _sock_link_pool; ///< socket pool
TNetItemPool _net_item_pool; ///< net handle pool
};
}
#endif