xzben 网络框架结构说明

来源:互联网 发布:java 常用加密算法 编辑:程序博客网 时间:2024/05/17 08:18

Source Code:

https://github.com/xzben/xzben

引言:


出于学习目的我编写了xzben框架,它是我一边学习一边写的,所以可能存在各种bug,如果你发现了bug可以在本博文留言,我一定会尽力解决。另外本框架注重在于网络通信的通行层,也就是说框架只是将网络通信中的数据包发送过程封装,可以让用户在不关心如何发送数据,只是关心通信协议层面上思考问题。所以请不要站在协议层上来看本框架,我并不关心协议是如何。我只关心如何高效的将数据发送出去,并在收到数据时告诉你让你拿数据去处理,仅此而已。


主要对象:

1、NetHost 对象代表一个网络主机对象,你只要给它装配好:IO驱动器(IODriver)、协议数据处理器(NetProtocol)然后启动服务,然后开始监听感兴趣的TCP/UDP端口(ListenTcpPort/ListenUdpPort),就已经安装好一个网络通信主机了。

2、IODriver 对象代表一个IO处理器对象基类,使用时应该使用具体的IODriver子类(由框架提供),比如目前提供的window下的IOCP模式(IOCPDriver)。

3、NetProtocol 对象代表一个协议数据处理器基类,用户需要自定实现一个具体的子类来处理数据实现自己的协议。

4、ShareNetSocketPtr 对象其实就代表一个NetSocket指针的代理器,由ShareNetSocketPtr代理NetSocket指针主要出于指针的保护。ShareNetSocketPtr本身就是一个智能指针对象,通过引用计数来控制对象的delete,当引用计数为零时NetSocket对象就会被delete,否则不会。所以在使用ShareNetSocketPtr时只要将其看成一个NetSocket指针就行。

5、NetSocket对象代表一个通信链路(TCP/UDP链路),它本身有自己链路的数据buffer所以,链路中的通信数据可以直接从它来获取(ReadMsg ),也可以直接用它来发送数据。

除了上面的五个类,其它的类你完全可以不关心,除非有bug的时候你才有必要去看。


使用步骤:

1、定义自己的通信协议类,主要实现

/**OnConnect接口在一个 TCP 连接建立时触发,可以在此接口中实现对连接到网络主机的Socket进行信息采集*@para pNetSocket:一个连接到主机的Socket连接封装类。可以在其中获取连接的通信数据,连接对象的地址信息也可以用它直接给通信对法发送数据。**/virtualbool OnConnect(ShareNetSocketPtr& pNetSocket) =0;/**OnDisconnect接口在一个TCP连接断开时触发,可以在此接口中采集与主机断开连接的的socket信息*@para pNetSocket: 同OnConnect*/virtual bool OnDisconnect(ShareNetSocketPtr& pNetSocket)=0;/**OnMsg 接口在接收到一个TCP/UDP 数据包是触发,要注意的是如果是TCP这里的触发次数不一定和发送端发送次数一致。*所以你要自己通过数据内容中的协议判断数据是否发送结束,不能假设一定一次触发就是一个完整的数据包。*@para pNetSocket: 同OnConnect*/virtual bool OnMsg(ShareNetSocketPtr& pNetSocket) =0;

example:

class TestProtocol : public NetProtocol{private:bool OnConnect(ShareNetSocketPtr& pNetSocket){std::string strIp; uint16 nPort;pNetSocket->GetPeertAddr(strIp, nPort);Print(GlobalFunction::Format("Connect Ip: %s --- Port: %d", strIp.c_str(), nPort));return true;}bool OnDisconnect(ShareNetSocketPtr& pNetSocket){std::string strIp; uint16 nPort;pNetSocket->GetPeertAddr(strIp, nPort);Print(GlobalFunction::Format("Disconnect Ip: %s --- Port: %d", strIp.c_str(), nPort));return true;}bool OnMsg(ShareNetSocketPtr& pNetSocket){char buffer[1024];static int nTimes = 1;int nDataSize = pNetSocket->GetDataSize();int nReadSize;if( (nReadSize = pNetSocket->ReadMsg(buffer, 1024)) > 0 ){buffer[nReadSize] = '\0';Print(GlobalFunction::Format("%d: OnMsg DataSize :%d Content: %s",nTimes++, nDataSize, buffer));pNetSocket->SendMessage(buffer, nReadSize);}return true;}private:void Print(std::string strMsg){AutoLock lock(&m_mutex);printf("%s\n", strMsg.c_str());}Mutex m_mutex;};
2、实例化一个NetHost对象,选择一个IODriver 子类作为其IO驱动器,将上面实现的协议类对象作为协议数据处理器。

3、启动服务,开始监听指定端口。

综合实例:

服务器Code:

#include <Socket/NetHost.h>#include <Socket/IOCPDriver.h>#include <Socket/NetProtocol.h>#include <base/Lock.h>#include <string>using namespace XZBEN;class TestProtocol : public NetProtocol{private:bool OnConnect(ShareNetSocketPtr& pNetSocket){std::string strIp; uint16 nPort;pNetSocket->GetPeertAddr(strIp, nPort);Print(GlobalFunction::Format("Connect Ip: %s --- Port: %d", strIp.c_str(), nPort));return true;}bool OnDisconnect(ShareNetSocketPtr& pNetSocket){std::string strIp; uint16 nPort;pNetSocket->GetPeertAddr(strIp, nPort);Print(GlobalFunction::Format("Disconnect Ip: %s --- Port: %d", strIp.c_str(), nPort));return true;}bool OnMsg(ShareNetSocketPtr& pNetSocket){char buffer[1024];static int nTimes = 1;int nDataSize = pNetSocket->GetDataSize();int nReadSize;if( (nReadSize = pNetSocket->ReadMsg(buffer, 1024)) > 0 ){buffer[nReadSize] = '\0';Print(GlobalFunction::Format("%d: OnMsg DataSize :%d Content: %s",nTimes++, nDataSize, buffer));pNetSocket->SendMessage(buffer, nReadSize);}return true;}private:void Print(std::string strMsg){AutoLock lock(&m_mutex);printf("%s\n", strMsg.c_str());}Mutex m_mutex;};int main(){NetHost *pHost = new NetHost(new IOCPDriver, new TestProtocol);pHost->StartServer();pHost->ListenTcpPort(6000);pHost->ThreadLoop();return 0;}

客户端Code:

#include <Socket/NetHost.h>#include <Socket/IOCPDriver.h>#include <Socket/NetProtocol.h>using namespace XZBEN;class ClientProtocol : public NetProtocol{private:bool OnConnect(ShareNetSocketPtr& pNetSocket){std::string strIp; uint16 nPort;pNetSocket->GetPeertAddr(strIp, nPort);Print(GlobalFunction::Format("Connect Ip: %s --- Port: %d", strIp.c_str(), nPort));return true;}bool OnDisconnect(ShareNetSocketPtr& pNetSocket){std::string strIp; uint16 nPort;pNetSocket->GetPeertAddr(strIp, nPort);Print(GlobalFunction::Format("Disconnect Ip: %s --- Port: %d", strIp.c_str(), nPort));return true;}bool OnMsg(ShareNetSocketPtr& pNetSocket){char buffer[1024];static int nTimes = 1;int nDataSize = pNetSocket->GetDataSize();int nReadSize;if( (nReadSize = pNetSocket->ReadMsg(buffer, 1024)) > 0 ){buffer[nReadSize] = '\0';Print(GlobalFunction::Format("%d: OnMsg DataSize :%d Content: %s",nTimes++, nDataSize, buffer));pNetSocket->SendMessage("TestBuffer", strlen("TestBuffer")+1);}return true;}private:void Print(std::string strMsg){AutoLock lock(&m_mutex);printf("%s\n", strMsg.c_str());}Mutex m_mutex;};int main(){NetHost host;host.SetupDriver(new IOCPDriver);host.SetupProtocol(new ClientProtocol);host.StartServer(1);SOCKET hSocket = host.Connect("127.0.0.1", 6000);host.SendTcpMsg(hSocket, "TestBuffer", strlen("TestBuffer")+1);host.ThreadLoop();return 0;}


0 0
原创粉丝点击