libevent 一种解析tcp包方式

1.首先定义传输协议时要包含包的长度,放在第一个位置。

2.使用一个标志标识接收到的数据长度,为0表示可以接收新的包数据。

3.在libevent源码中添加一个获取bufferevent接收数据缓冲区中有效的数据大小,加在bufferevent.c 中代码如下:

unsigned int  buffer_get_validinputbyte(struct bufferevent* bufev)
{
	if (!bufev)return 0;
	unsigned int byteAvaliable = 0;
	struct evbuffer_chain* chain = bufev->input->first;
	while (chain)
	{
		byteAvaliable += chain->off;
		chain = chain->next;
	}
	return byteAvaliable;
}

4.读取时判断buffer中数据是否完整,如果完整读取,参考代码:

void socket_read_cb(bufferevent* bev, void* arg)
{
	struct event_base* base = (event_base*)arg;

	size_t len;
	// 这里一行一行的读取

	char lenbuf[2] = { 0 };
	evutil_socket_t fd = bufferevent_getfd(bev);

	if (auto client = gDataMgr->client(fd))
	{
		unsigned int _byteAvaliable = buffer_get_validinputbyte(bev);
		if (client->inBlockSize() == 0) //如果是刚开始接收数据
		{
			if (_byteAvaliable < sizeof(unsigned short)) return;
			len = bufferevent_read(bev, lenbuf, 2);
			if (len != 2)return;
			client->setInblockSize(Utils::intergerFromStr(lenbuf,2)); //网络字节序
		}

		_byteAvaliable = buffer_get_validinputbyte(bev);
		if (_byteAvaliable < (uint)client->inBlockSize()) return;
		len = bufferevent_read(bev, client->inBlockBuffer(), client->inBlockSize());
		if (len != client->inBlockSize())
		{
			printf("socket_read_cb::read data error!");
			return;
		}
		client->process();
	}
}

这样可以保证在client的process函数中处理的肯定是完整数据包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值