轻量、稳定、高效的IOCP模型框架,支持速度统计与限速、自动拆包封包,可直接用于生产环境。

Panke 2012-08-12 09:31:07
先贴出头文件。

#ifndef NetNoteInterface_h__
#define NetNoteInterface_h__

#pragma once

#pragma pack(1)
struct SessionIO;

namespace net
{
enum NetEvent //网络事件枚举
{
net_START,
net_STOP,
net_CONNECT,
net_DISCONNECT,
net_RECV,
net_SEND
};

enum RetEvent //网络事件状态枚举
{
ret_SUCCESSED,
ret_ERROR,
ret_FAILED,
ret_SENDBEFORE,
};

struct NetAddr //服务器端或客户端ip与端口
{
char mAddr[32];
int mPort;
};

struct SpeedTotal //TCP通讯统计
{
INT64 m_SCurrent_Speed; //当前发送速度
INT64 m_RCurrent_Speed; //当前接收速度
INT64 m_SAverageSpeed; //平均发送速度
INT64 m_RAverageSpeed; //平均接收速度
INT64 m_Total_Send; //总发送字节数
INT64 m_Total_Recv; //总接收字节数
INT64 m_Total_SendNum; //总发送次数
INT64 m_Total_RecvNum; //总接收次数
INT64 m_Start_Tick; //开始时间
INT64 m_SLast_Tick; //最后发送数据时间
INT64 m_RLast_Tick; //最后接收数据时间
INT64 m_Elapsed_Tick; //已逝去时间或结束时间
INT m_Send_QueueLenght; //发送列队长度
INT m_Recv_QueueLenght; //接收列队长度
CHAR m_Start_Time[32]; //开始时间
CHAR m_SLast_Time[32]; //最后发送数据时间
CHAR m_RLast_Time[32]; //最后接收数据时间
CHAR m_Elapsed_Time[32]; //已逝去时间或结束时间
};

//网络事件接口
typedef class NetNoteInterface
{
public:
virtual NetNoteInterface* createNetNote(){return NULL;};//作为服务器节点接口时才有效,在此方法实例化客户端对象,一般为自身
virtual void OnNetNotify(const char* _data,int _len,NetEvent _NetEvent,RetEvent _RetEvent,SessionIO* _Session){};//网络事件通知
virtual void OnNetNotify(const char* _data,int _len,NetEvent _NetEvent,RetEvent _RetEvent,NetNoteInterface* _NetNote){};//网络事件通知
virtual void OnNetNotify(const char* _data,int _len,NetEvent _NetEvent,RetEvent _RetEvent,int _NetIndex){};//网络事件通知
virtual void SpeedTotalNotify(SpeedTotal _SpeedTotal){};//速度统计通知
public:
NetAddr mNetAddr;//当前节点IP地址和端口,由类库填充
}CNetNote;

//网络通信类库接口,服务器端与客户端合并为一个对象
class CNetLibInterface
{
public:
//初始化为服务器对象
virtual void InitServer(bool _ConsoleLog = true,const char* _LogFilePath = "") = 0;
//初始化为客户端对象
virtual void InitClient(bool _ConsoleLog = true,const char* _LogFilePath = "") = 0;
//启动服务器端监听,为服务器端对象时生效
virtual void StartServer(net::CNetNote* _NetNote,int _Port,char* _Addr = NULL,bool _EnableSpeedTotal = false) = 0;
//停止服务器端
virtual void StopServer(void) = 0;
//限制连接数,为服务器端时生效
virtual void ConnectionLimit(int _MaxConnect = 200) = 0;
//断开指定客户端连接,为服务器端时生效
virtual void DisConnectAt(int _NetIndex) = 0;
//断开所有连接
virtual void DisConnectAll() = 0;
//获取指定客户端节点对象
virtual CNetNote* GetNetNoteAt(int _NetIndex) = NULL;
//获取指定客户端节点对象索引
virtual int GetIndexAt(CNetNote* _NetNode) = NULL;
//获取指定客户端节点对象索引
virtual int GetIndexAt(SessionIO* _SessionIO) = NULL;
//向指定节点发送数据
virtual void Send(const char* _Buff,int _Len,SessionIO* _Session) = 0;
//向指定节点发送数据
virtual void Send(const char* buf,int _len,int _NetIndex = 0) = 0;
//向指定节点发送数据
virtual void Send(const char* buf,int _len,CNetNote* _NetNotePtr) = 0;
//向指所有节点发送数据
virtual void SendToAllCli(const char* _Buff,int _Len) = 0;
//当前对象是否为客户端
virtual bool IsConnect(void) = 0;
//当前对象是否为服务器端
virtual bool IsStarted(void) = 0;
//连接服务器端,为客户端时生效
virtual void Connect(net::CNetNote* _NotePtr,char* _IpAddr,int _Port,bool _EnableSpeedTotal = false) = 0;
//当前连接数
virtual int GetConnectCount(void) = 0;
//开启速度统计,并设置速度统计间隔
virtual bool StartSpeedTotal(UINT _DelaySetp) = 0;
//关闭速度统计
virtual void StopSpeedTotal(void) = 0;
//发送与接收的限速设置
virtual void SetSpeedLimit(int _Sbytes = 0,int _Rbytes = 0) = 0;
//设置缓冲池最大列队数
virtual void SetMaxCacheQueue(int _MaxCacheQueue) = 0;
};

typedef net::CNetLibInterface CNetworkLib;

//服务器端对象
class CNetServerInterface
{
public:
virtual void InitServer(bool _Console = true,string _LogFilePath = "") = 0;
virtual void StartServer(net::CNetNote* _NetNote,int _Port,char* _Addr = NULL,bool _EnableSpeedTotal = false) = 0;
virtual void StopServer() = 0;
virtual void ConnectionLimit(int _MaxConnect = 200) = 0;
virtual void Send(const char* _Buff,int _Len,SessionIO* _Session) = 0;
virtual void Send(const char* _Buff,int _Len,net::NetNoteInterface* _NetNode) = 0;
virtual void Send(const char* _Buff,int _Len,int _NetIndex) = 0;
virtual void SendToAllCli(const char* _Buff,int _Len) = 0;
virtual void DisConnectAt(int _NetIndex) = 0;
virtual void DisConnectAt(SessionIO* _Session) = 0;
virtual void DisConnectAll() = 0;
virtual int GetConnectCount() = 0;
virtual int GetIndexAt(CNetNote* _NetNode) = NULL;
virtual int GetIndexAt(SessionIO* _SessionIO) = NULL;
virtual SessionIO* GetAt(int _NetIndex) = NULL;
virtual SessionIO* GetAt(net::NetNoteInterface* _NetNote) = NULL;
virtual bool IsStarted(void) = 0;

virtual bool StartSpeedTotal(UINT _DelaySetp) = 0;
virtual void StopSpeedTotal(void) = 0;
virtual void SetSpeedLimit(int _Sbytes = 0,int _Rbytes = 0) = 0;
virtual void SetMaxCacheQueue(int _MaxCacheQueue) = 0;
};

typedef net::CNetServerInterface CNetServerLib;

//客户端对象
class CNetClientInterface
{
public:
virtual void InitClient(bool _Console = true,string _LogFilePath = "") = 0;
virtual void Connect(net::CNetNote* _NotePtr,char* _Addr,int _Port,bool _EnableSpeedTotal = false) = 0;
virtual bool IsConnected(void) = 0;
virtual void DisConnect() = 0;
virtual void Send(const char* _Buff,int _Len) = 0;

virtual bool StartSpeedTotal(UINT _DelaySetp) = 0;
virtual void StopSpeedTotal(void) = 0;
virtual void SetSpeedLimit(int _Sbytes = 0,int _Rbytes = 0) = 0;
virtual void SetMaxCacheQueue(int _MaxCacheQueue) = 0;
};

typedef net::CNetClientInterface CNetClientLib;

//HTTP客户端对象
class CHttpClientLib
{
public:
//向指定URL发送请求,并返回HTML源码
virtual int SendRequest( string url,string& pszResultHtmlSrc,bool IsPost = false ) = 0;
//向指定URL发送请求,并返回HTML源码
virtual int SendRequest( string url,string& pszResultHtmlSrc,string& pszResultHtmlHeaderReceive,bool IsPost = false ) = 0;
//向指定URL发送请求,并返回HTML源码
virtual int SendRequest( string url,string& pszResultHtmlSrc, string& pszResultHtmlHeaderReceive, string& pszResultHtmlHeaderSend,bool IsPost = false ) = 0;
//正则匹配函数,该正则为ATL正则匹配
virtual int MatchString(string _StringSrc,string _ParseStr,vector<string>& _pszResult) = 0;
};
#endif

//通过模板封装网络通信接口,以达到使用更灵活及方便的目的
template<class T>
class CNetworkCore
{
public:
CNetworkCore( T* _NetNote,CNetworkLib* _pNetworkLib = getNetworkLib())
{
pNetLib = _pNetworkLib;
pNodePtr = _NetNote;
}

~CNetworkCore( void )
{
delete pNetLib;
pNetLib = NULL;
}

public:
void StartServer( int _Port,char* _Addr = NULL,bool _EnableSpeedTotal = false )
{
pNetLib->StartServer((CNetNote*)pNodePtr,_Port,_Addr,_EnableSpeedTotal);
}

void Connect( char* _IpAddr,int _Port,bool _EnableSpeedTotal = false )
{
pNetLib->Connect((CNetNote*)pNodePtr,_IpAddr,_Port,_EnableSpeedTotal);
}

T* GetNodePtr( int _NetIndex )
{
return (T*)pNetLib->GetNetNoteAt(_NetIndex);
}

T* GetDefaultNotePtr()
{
return pNodePtr;
}

int GetIndexAt(CNetNote* _NetNode)
{
return pNetLib->GetIndexAt(_NetNode);
}

int GetIndexAt(SessionIO* _SessionIO)
{
return pNetLib->GetIndexAt(_SessionIO);
}

void StopServer( void )
{
pNetLib->StopServer();
}

void ConnectionLimit( int _MaxConnect = 200 )
{
pNetLib->ConnectionLimit(_MaxConnect);
}

void DisConnectAt( int _NetIndex )
{
pNetLib->DisConnectAt(_NetIndex);
}

void DisConnectAll()
{
pNetLib->DisConnectAll();
}

void Send( const char* _Buff,int _Len,SessionIO* _Session )
{
pNetLib->Send(buf,_len,_Session);
}

void Send( const char* buf,int _len,int _NetIndex = 0 )
{
pNetLib->Send(buf,_len,_NetIndex);
}

void Send( const char* buf,int _len,T* _NetNotePtr)
{
pNetLib->Send(buf,_len,(CNetNote*)_NetNotePtr);
}

void SendToAllCli(const char* _Buff,int _Len)
{
pNetLib->SendToAllCli(_Buff,_Len);
}

bool IsConnect( void )
{
return pNetLib->IsConnect();
}

bool IsStarted(void)
{
return pNetLib->IsStarted();
}

int GetConnectCount( void )
{
return pNetLib->GetConnectCount();
}

bool StartSpeedTotal( UINT _DelaySetp )
{
return pNetLib->StartSpeedTotal(_DelaySetp);
}

void StopSpeedTotal( void )
{
pNetLib->StopSpeedTotal();
}

void SetSpeedLimit( int _Sbytes = 0,int _Rbytes = 0 )
{
pNetLib->SetSpeedLimit(_Sbytes,_Rbytes);
}

void SetMaxCacheQueue( int _MaxCacheQueue )
{
pNetLib->SetMaxCacheQueue(_MaxCacheQueue);
}

CNetworkLib* GetNetworkLib()
{
return pNetLib;
}

void SetNetworkLib(CNetworkLib* _pNetworkLib)
{
pNetLib = _pNetworkLib;
}

private:
CNetLibInterface* pNetLib;
T* pNodePtr;
};
}
#pragma pack()
#endif // NetNoteInterface_h__



使用例子

int main(void)
{
CNetworkCore<CNetworkNodes> mServer(new CNetworkNodes());
mServer->StartServer(16580,NULL,true);

while(1)
Sleep(100);
return 0
}


下载地址
http://download.csdn.net/detail/ipanke/4494864
...全文
1720 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
sxcong 2012-12-14
  • 打赏
  • 举报
回复
自libuv问世, 感觉其他网络库都可以省略了,连MS自己都在用
liangbina07 2012-12-11
  • 打赏
  • 举报
回复
鄙视一下,我以为是什么好东西准备下了研究了下,还好看到了下面的评论了。fuck!
ms2146 2012-12-11
  • 打赏
  • 举报
回复
貌似骗分的。。。法克。
「已注销」 2012-08-30
  • 打赏
  • 举报
回复
中国人写的完成端口应用都存在并发隐患。
smwhotjay 2012-08-28
  • 打赏
  • 举报
回复

懒说话
wapjia43106140 2012-08-28
  • 打赏
  • 举报
回复
一看这个接口就有BUG.
wapjia43106140 2012-08-28
  • 打赏
  • 举报
回复
没代码不要拿出来.说不定里面错误百出.

可能没有明白IOCP也写个出来哈
Eleven 2012-08-22
  • 打赏
  • 举报
回复
nrxtgcb 2012-08-22
  • 打赏
  • 举报
回复
没有源码吗?
w88529593 2012-08-22
  • 打赏
  • 举报
回复
垃圾的东西,大家不要被这个骗子骗了,只有静态库和DLL,就这还要5分,你真是个大 S B 啊
yipihaoma 2012-08-14
  • 打赏
  • 举报
回复
垃圾 只是个dll 没有源码
melos 2012-08-12
  • 打赏
  • 举报
回复
马克一下,感谢分享
最近有项目要做一个高性能网络服务器,决定下功夫搞定完成端口(IOCP),最终花了一个星期终于把它弄清楚了,并用C++写了一个版本,效率很不错。 但,从项目的总体需求来考虑,最终决定上.net平台,因此又花了一天一夜弄出了一个C#版,在这与大家分享。 一些心得体会: 1、在C#中,不用去面对完成端口的操作系统内核对象,Microsoft已经为我们提供了SocketAsyncEventArgs类,它封装了IOCP的使用。请参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socketasynceventargs.aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1。 2、我的SocketAsyncEventArgsPool类使用List对象来存储对客户端来通信的SocketAsyncEventArgs对象,它相当于直接使用内核对象时的IoContext。我这样设计比用堆栈来实现的好处理是,我可以在SocketAsyncEventArgsPool池中找到任何一个与服务器连接的客户,主动向它发信息。而用堆栈来实现的话,要主动给客户发信息,则还要设计一个结构来存储已连接上服务器的客户。 3、对每一个客户端不管还发送还是接收,我使用同一个SocketAsyncEventArgs对象,对每一个客户端来说,通信是同步进行的,也就是说服务器高度保证同一个客户连接上要么在投递发送请求,并等待;或者是在投递接收请求,等待中。本例只做echo服务器,还未考虑由服务器主动向客户发送信息。 4、SocketAsyncEventArgs的UserToken被直接设定为被接受的客户端Socket。 5、没有使用BufferManager 类,因为我在初始化时给每一个SocketAsyncEventArgsPool中的对象分配一个缓冲区,发送时使用Arrary.Copy来进行字符拷贝,不去改变缓冲区的位置,只改变使用的长度,因此在下次投递接收请求时恢复缓冲区长度就可以了!如果要主动给客户发信息的话,可以new一个SocketAsyncEventArgs对象,或者在初始化中建立几个来专门用于主动发送信息,因为这种需求一般是进行信息群发,建立一个对象可以用于很多次信息发送,总体来看,这种花销不大,还减去了字符拷贝和消耗。 6、测试结果:(在我的笔记本上时行的,我的本本是T420 I7 8G内存) 100客户 100,000(十万次)不间断的发送接收数据(发送和接收之间没有Sleep,就一个一循环,不断的发送与接收) 耗时3004.6325 秒完成 总共 10,000,000 一千万次访问 平均每分完成 199,691.6 次发送与接收 平均每秒完成 3,328.2 次发送与接收 整个运行过程中,内存消耗在开始两三分种后就保持稳定不再增涨。 看了一下对每个客户端的延迟最多不超过2秒。
完成端口通讯服务器(IOCP Socket Server)设计 (六)功能强大的IOCP Socket Servre模块例程源码 Copyright © 2009 代码客(卢益贵)版权所有 QQ:48092788 源码博客:http://blog.csdn.net/guestcode 一、声明 版权声明: 1、通讯模块代码版权归作者所有; 2、未经许可不得全部或部分用于任何项目开发; 3、未经许可不得部分修改后再利用源码。 免责声明: 1、 由于设计缺陷或其它Bug造成的后果,作者不承担责任; 2、未经许可的使用作者不提供任何技术支持服务。 权利和义务: 1、任何获得源码并发现Bug的个人或单位均有义务向作者反映; 2、作者保留追究侵权者法律责任的权利。 二、开发背景 部分代码由前项目分离而来,尚未有应用考验,但对于初学者学习和进阶有很大帮助。性能上尚未有定论,但应该不会令你失望。 三、功能说明 1、可以关闭Socket的Buffer; 2、可以关闭MTU(不等待MTU满才发送); 3、可以多IP或多端口监听; 4、可以重用socket(主动关闭除外); 5、可以0缓冲接收(Socket的Buffe = 0时,避免过多的锁定内存页); 6、可以0缓冲连接(客户端仅连接,不一定立即发数据); 7、可以条件编译: a、是否使用内核Singly-linked lists; b、是否使用处理线程(工作线程和处理线程分开); c、是否使用内核锁来同步链表。 8、可以实现集群服务器模式的通讯(有客户端socket); 9、可以单独设置每个连接的Data项来实现连接和Usernfo的关联; 10、每个线程有OnBegin和OnEnd,用于设置线程独立的对象(数据库会话对象); 11、可以提供详细的运行情况,便于了解IOCP下的机制,以及进行调试分析; 12、可以发起巨量连接和数据(需要硬件配置来支持)。

1,649

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 非技术类
社区管理员
  • 非技术类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧