xzben 网络框架结构说明

Source Code:

引言:


出于学习目的我编写了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连接封装类。可以在其中获取连接的通信数据,连接对象的地址信息也可以用它直接给通信对法发送数据。
	*	
	*/
	virtual	bool 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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值