基于libevent的tcp拆包分包库
TCP/IP协议虽然方便,但是由于是基于流的传输(UDP是基于数据报的传输),无论什么项目,总少不了解决拆包分包问题。
以前的项目总是每个程序员自己写一套拆包分包逻辑,实现的方法与稳定性都不太一致。终于有了做基线的机会,自己写了一个基于libevent的拆包分包库。
本文档黏贴一些核心的内容。
//回调接口
| class ITcpPacketNotify { public: virtual void OnConnected(int fd) = 0; virtual void OnDisConnected(int fd) = 0; virtual void OnTimeOutError(int fd) = 0; virtual void OnBuffOverFlow(int fd) = 0; //提取包,需要业务层返回解析出包的长度,或者舍弃一些不合格的包,成功解析出包返回true virtual bool OnAnalyzePacket(int fd,const char* buff,int bufflen,int& packetlen,int &ignore) = 0; //业务层处理包回调,如果需要返回包,可以直接在respond参数和respondlen参数返回,长度不得超过40960 virtual void OnPacketArrived(int fd,const char* packet,int packetlen,char* respond,int& respondlen) = 0; }; |
提供了两种错误情况的通知,跟别的库不太一样的地方是,需要业务层实现拆包逻辑,毕竟每个项目的协议不一样。然后就会收到packet的通知。
|
//提取包,需要业务层返回解析出包的长度,或者舍弃一些不合格的包,成功解析出包返回true virtual bool OnAnalyzePacket(int fd, const char* buff, int bufflen,int& packetlen, int &ignore) //数据长度 packetlen = length + 12; |
上面是某种协议的拆包例子。
|
typedef struct _TcpPacketConfig _TcpPacketConfig() } TcpPacketConfig; class ITcpPacketManager TCPPACKET_API ITcpPacketManager* CreateTcpPacketManager(); TCPPACKET_API void DestroyTcpPacketManager(ITcpPacketManager* manager); |
对外的接口方法。
|
bool CTcpPacketImp::Start(_TcpPacketConfig & config, ITcpPacketNotify* notify) void CTcpPacketImp::Stop() bool CTcpPacketImp::SendPacket(int fd, const char* packet, int packetlen) |
转移到m_libEvent实现。
最核心的功能代码如下。
一些数据定义:
|
#include <event2/bufferevent.h> struct _Conn; //服务器属性封装对象 typedef struct _Server Server; |
头文件:
|
class CLibEvent static ITcpPacketNotify * m_notify; |
cpp:
|
#include "StdAfx.h" #include <string> #include <assert.h> #include <WinSock2.h> CLibEvent::CLibEvent(void) CLibEvent::~CLibEvent(void) bool CLibEvent::StartServer(int port, short workernum, unsigned int connnum, int read_timeout, int write_timeout,ITcpPacketNotify* notify) void CLibEvent::StopServer() void CLibEvent::DoRead(struct bufferevent *bev, void *ctx) //拷贝缓冲池的内存到Conn,最大缓冲不超过emMaxBuffLen } } void CLibEvent::CloseConn(Conn *pConn) void CLibEvent::DoError(struct bufferevent *bev, short error, void *ctx) void CLibEvent::DoAccept(struct evconnlistener *listener, evutil_socket_t fd,struct sockaddr *sa, int socklen, void *user_data) DWORD WINAPI CLibEvent::ThreadServer(LPVOID lPVOID) DWORD WINAPI CLibEvent::ThreadWorkers(LPVOID lPVOID) bool CLibEvent::SendPacket(int fd, const char* packet, int packetlen) return true; ITcpPacketNotify * CLibEvent::m_notify=NULL; |
基于libevent的tcp拆包分包库的更多相关文章
- 基于 libevent 开发的 C++ 11 高性能网络服务器 evpp(360的作品)
evpp是一个基于libevent开发的现代化C++11高性能网络服务器,自带TCP/UDP/HTTP等协议的异步非阻塞式的服务器和客户端库. 特性: 现代版的C++11接口 非阻塞异步接口都是C++ ...
- PHP写的异步高并发服务器,基于libevent
PHP写的异步高并发服务器,基于libevent 博客分类: PHP PHPFPSocketLinuxQQ 本文章于2013年11月修改. swoole已使用C重写作为PHP扩展来运行.项目地址:h ...
- 基于libevent, libuv和android Looper不断演进socket编程 - 走向架构师之路 - 博客频道 - CSDN.NET
基于libevent, libuv和android Looper不断演进socket编程 - 走向架构师之路 - 博客频道 - CSDN.NET 基于libevent, libuv和android L ...
- 公布一个基于 Reactor 模式的 C++ 网络库
公布一个基于 Reactor 模式的 C++ 网络库 陈硕 (giantchen_AT_gmail) Blog.csdn.net/Solstice 2010 Aug 30 本文主要介绍 muduo 网 ...
- 基于“泵”的TCP通讯(接上篇)
基于“泵”的TCP通讯(接上篇) 上一篇博客中说了基于“泵”的UDP通讯,附上了一个Demo,模拟飞鸽传书的功能,功能不太完善,主要是为了说明“泵”在编程中的应用.本篇文章我再附上一个关于TCP通讯的 ...
- Netty系列(四)TCP拆包和粘包
Netty系列(四)TCP拆包和粘包 一.拆包和粘包问题 (1) 一个小的Socket Buffer问题 在基于流的传输里比如 TCP/IP,接收到的数据会先被存储到一个 socket 接收缓冲里.不 ...
- libevent实现TCP 服务端
libevent实现Tcp Server基于bufferevent实现 /******************************************************** Copyri ...
- 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载
一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...
- 基于Libevent的HTTP Server
简单的Http Server 使用Libevent内置的http相关接口,可以很容易的构建一个Http Server,一个简单的Http Server如下: #include <event2/e ...
随机推荐
- Oracle EBS SLA 详解
SLA概述 SLA :子分类账(Subledger Accounting),这个在R12中大力宣扬的内容,我们通常的认为总账就是对Journal的汇总,但是在实际的操作中我们会发现,对于Sub sys ...
- JavaScript中的三种弹出对话框
学习过js的小伙伴会发现,我们在一些实例中用到了alert()方法.prompt()方法.prompt()方法,他们都是在屏幕上弹出一个对话框,并且在上面显示括号内的内容,使用这种方法使得页面的交互性 ...
- UITableView大总结(上)
1.UITableView继承UIScrollView. 2.实例一城市列表思路: 步骤一:创建UITableView.UITableView样式为组 步骤二:设置UITableView的数据源方法. ...
- 单元测试junit框架详解
首先在给出一个类Operator,加入如下代码: public class Operator { // 加法 运算 public int add(int i,int j){ return i+j; } ...
- 【一天一道LeetCode】#62. Unique Paths
一天一道LeetCode系列 (一)题目 A robot is located at the top-left corner of a m x n grid (marked 'Start' in th ...
- H5学习之旅-H5的块标签的使用(9)
块元素的基本语法 1. Html块元素 ,块元素在开始时候通常以新行开始,比如h1,p,ul 2.内联元素,通常不会以新行开始,比如a,b,img 3.html的div元素,div也被称为块元素,其主 ...
- 【一天一道LeetCode】#48. Rotate Image
一天一道LeetCode系列 (一)题目 You are given an n x n 2D matrix representing an image. Rotate the image by 90 ...
- 【翻译】Sencha Ext JS 5发布
原文:Announcing Sencha Ext JS 5 简介 我代表Sencha和整个Ext JS团队,很自豪的宣布,在今天,Sencha Ext JS 5发布了.Ext JS 5已经迈出了一大步 ...
- C语言实现ifconfig获取网卡接收和发送流量统计
在Windows下我们可以利用ipconfig命令获取网卡的相关信息,在Linux下命令是ifconfig 我们可以获取的信息更为丰富,其中包括网卡接收和发送的流量,用C语言实现这个命令并不是一件简单 ...
- Android和iOS中Cocos2D日志为什么会出现skip frames
在你运行app在Android或iOS设备或iOS模拟器中时,日志里往往会出现一行: I/Choreographer(28956): Skipped 159 frames! The applicati ...