`
关中刀客
  • 浏览: 26213 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

仿mbuf机制实现自己的不定长内存池

阅读更多
最近在考虑一个客户端底层通讯模块的实现问题,我需要做的就是把我的套接字绑定到窗口上,当套接字有事件产生,比如可读,关闭等消息的时候,直接通过窗口消息通知我,我在做一定的处理,客户端需要实现一个可伸缩的内存池来管理通讯的数据,上层在一桢中可压入许多待发送的数据,底层在一桢可接受许多服务器端的数据。所以我打算使用变长的内存池来实现,以前看过tcp/ip底层的mbuf实现机制,感觉很不错,所以这次做了一些改进,来实现我的不定长内存池策略。
/* 
* Copyright(c)2008 
* 
* 文件名称:  mbuf 
* 文件标识: 
* 摘    要: 仿照tcp/ip的mbuf机制实现自己的mbuf 
			pWriter只仅仅表示我们当前的写指针位置,
			而我们的iUnused只仅仅的表示我们的写指
			针位置距离我们的buff+MBUF_BUFFER_SIZE
			还有多少个可用字节数目。
			pReader只仅仅表示我们当前的读指针位置,
			而我们的iUsed也只仅仅表示我们的读指针
			位置距离我们的pWriter指针还有多少字节
			这个再次注意,我们的iUnused+iUsed不一定
			就等于buff的总体长度MBUF_BUFFER_SIZE,
			这两者之间没有任何联系
* 
* 当前版本: cobra_for_window 1.00 
* 作    者: 关中刀客 
* E-Mail  : guanzhongdaoke@gmail.com 
* Blog    : http://guan-zhong-dao-ke.blog.163.com/ 
* 完成时间: 2008年04月22日 
*/ 


#include <Windows.h>


struct  mbuf
{
public:
	enum
	{
		MBUF_BUFFER_SIZE = 2048
	};

public:
	struct  mbuf*  pNext;
	struct  mbuf*  pRef;
	char*          pReader;
	char*          pWriter;
	size_t         iUsed;
	size_t         iUnused;
	char           buff[MBUF_BUFFER_SIZE];

public:
	inline  void  init_mbuf()
	{
		pNext    =  NULL;
		pRef     =  this;
		pReader  =  buff;
		pWriter  =  buff;
		iUsed    =  0;
		iUnused  =  MBUF_BUFFER_SIZE;
		
		memset(buff, 0, sizeof(buff));
	}
};


struct  mbuf;
class   mbufpool
{
private:
	struct  mbuf*  m_pBegin;
	struct  mbuf*  m_pEnd;
	struct  mbuf*  m_pFinish;
	size_t         m_iBytes;

public:
	mbufpool();
	~mbufpool();

public:
	/*
		得到数据开始的节点
	*/
	mbuf*    begin();
	/*
		得到数据结尾的节点
	*/
	mbuf*    end();
	/*
		得到当前mbufpool中所存字节的总数
	*/
	size_t   get_bytes_number();
	/*
		设计当前mbufpool中所存字节的总数
	*/
	void     set_bytes_number(size_t iBytes);
	/*
		增加制定数目的mbuf节点
	*/
	void     resize(size_t iNum);
	/*
		m_pBegin向后移动
	*/
	void     next();
	/*
		压入一些节点
	*/
	void     push_node(mbuf* pNode);
	/*
		压入一定长度的数据
	*/
	void     push_data(const char* pData, size_t iNum);
	/*
		得到一定数目的字节
	*/
	bool     pop_data(char* pData, size_t iNum);
	/*
		销毁mbufpool
	*/
	void     destroy();

private:
	/*
		从系统中分配节点
	*/
	void     malloc_mbuf_from_system();
};



class cobra_socket
{
private:
	SOCKET    m_sock;
	mbufpool  m_recvpool;
	mbufpool  m_sendpool;

public:
	cobra_socket();
	~cobra_socket();

public:
	void    init_cobra_socket(size_t iRecvpollSize, size_t iSendPoolSize);
	bool    create_socket();
	bool    connect_to_server(const char* pIP, u_short port);
	bool    bind_to_window(HWND hWnd, int wMsg, int iMsg);
	bool    logic_recv(char* pBuff, size_t iNum);
	void    logic_send(const char* pBuff, size_t iNum);
	bool    start_recv();
	bool    start_send();
	void    close_socket();
	void    destroy_cobra_socket();
};
感觉这个方法挺不错的,当然,如果各位朋友有更好的建议或者意见的话,欢迎和我联系^__^
分享到:
评论
3 楼 dan199011 2012-12-09  
LZ  还有实现功能的其他具体代码么?想借鉴一下,,
我邮箱 wcd2011_1990@126.com

谢谢了哦!!!
2 楼 关中刀客 2008-05-23  
呵呵,有时间看看libevent的那些东西^__^
1 楼 iunknown 2008-05-22  
libevent 最新的代码库中,也开始加入了类似的 buffer_chain 。
在 ACE 中,有 MsgBlock 类,也是实现这种功能的。


贴代码用一下代码标签吧,要不然很难看。

相关推荐

Global site tag (gtag.js) - Google Analytics