码迷,mamicode.com
首页 > 编程语言 > 详细

分享一个自己使用了很久的C++网络封装库,包含服务端和客户端,支持跨平台

时间:2015-07-30 11:03:45      阅读:325      评论:0      收藏:0      [点我收藏+]

标签:

其实就只是对网络底层的一个封装,一些回调全部都已经封装好,直接指定相应的回调函数就可以对收到的数据包进行处理。

个人觉得该网络库比较方便的地方就是可以直接将所有自定义及C++标准库容器直接发送到服务端,而原始的C函数发送时连续存储的内存。

注意,该库使用C11编译,所以客户端必须支持C11,废话不多说下面直接看使用demo。

 

协议定义(protocols.h)

 1 #pragma once  
 2 #include "protocolbase.h"  
 3   
 4   
 5 //客户端请求登录  
 6 class QLogin :public Net::ProtocolBase  
 7 {  
 8 public:  
 9     QLogin() = default;  
10     ~QLogin() = default;  
11   
12     Serialize(QLogin)  
13     {  
14         ar(uClientId, strUsername, strPassword);  
15     }  
16   
17     Net::UInt32 uClientId;  
18     std::string strUsername;  
19     std::string strPassword;  
20 };  
21   
22 //客户端请求数据  
23 class QData :public Net::ProtocolBase  
24 {  
25 public:  
26     QData() = default;  
27     ~QData() = default;  
28   
29     Serialize(QData)  
30     {  
31   
32     }  
33 };  
34   
35   
36 //响应客户端登录  
37 class RLogin :public Net::ProtocolBase  
38 {  
39 public:  
40     RLogin() = default;  
41     ~RLogin() = default;  
42   
43     Serialize(RLogin)  
44     {  
45         ar(strErrorInfo);  
46     }  
47   
48     std::string strErrorInfo;  
49 };  
50   
51 class CustomData  
52 {  
53 public:  
54     CustomData() = default;  
55     ~CustomData() = default;  
56   
57     Serialize(CustomData)  
58     {  
59         ar(nData, fData, dData, shData);  
60     }  
61   
62     int nData;  
63     float fData;  
64     double dData;  
65     short shData;  
66 };  
67   
68   
69 //响应客户端请求数据  
70 class RData :public Net::ProtocolBase  
71 {  
72 public:  
73     RData() = default;  
74     ~RData() = default;  
75   
76     Serialize(RData)  
77     {  
78         ar(strNickname, bSex, uAge, strEmail, vData, mData, customData);  
79     }  
80   
81     std::string strNickname;  
82     bool bSex;  
83     Net::UInt8 uAge;  
84     std::string strEmail;  
85     std::vector<std::string> vData;  
86     std::map<std::string,std::pair<int,float> > mData;  
87     CustomData customData;  
88 };  

 

main.cpp

#include "socketserver.h"
#include "socketclient.h"

#include "protocols.h"

#include <iostream>


class ServerSocketSession :public Net::SocketSession
{
public:
	ServerSocketSession() = default;
	~ServerSocketSession()
	{
		
	}
	ServerSocketSession(const ServerSocketSession&) = delete;
	ServerSocketSession& operator = (const ServerSocketSession&) = delete;

	//响应用户登录
	void userLogin(std::shared_ptr<QLogin> r)
	{
		auto result = std::make_shared<RLogin>();
		if (r->uClientId == 123456 && 
			r->strUsername == "123456" &&
			r->strPassword == "123456")
		{
			result->strErrorInfo = "LoginSucceed";
		}
		else
		{
			result->strErrorInfo = "LoginFailure";	
		}
		send(result);
	}

	//响应用户请求详细数据
	void userData(std::shared_ptr<QData> r)
	{
		auto result = std::make_shared<RData>();

		result->strNickname = "winter";
		result->bSex = true;
		result->strEmail = "winter@gmail.com";
		result->uAge = 100;
		result->mData.emplace("m1",std::make_pair(1111,111.111f));
		result->mData.emplace("m2", std::make_pair(2222, 222.222f));
		result->mData.emplace("m3", std::make_pair(3333, 333.333f));

		result->vData.push_back("v1");
		result->vData.push_back("v2");
		result->vData.push_back("v3");
		result->vData.push_back("v4");

		result->customData.dData = -10000000.000001f;
		result->customData.fData = 100000.00002f;
		result->customData.nData = -100000;
		result->customData.shData = -100;
		send(result);
	}
};

class ClientSocketSession
{
public:
	ClientSocketSession()
	:m_socketClient("127.0.0.1", 6691, true)
	{
		m_socketClient.registerProtocol(&ClientSocketSession::onUserLogin, this);
		m_socketClient.registerProtocol(&ClientSocketSession::onUserData, this);
		m_socketClient.registerProtocol(&ClientSocketSession::onSocketEvent, this);


		m_socketClient.connect();
	}


	~ClientSocketSession() = default;
	ClientSocketSession(const ClientSocketSession&) = delete;
	ClientSocketSession& operator = (const ClientSocketSession&) = delete;

	void update(){ m_socketClient.update(); }

	void onSocketEvent(std::shared_ptr<Net::SocketEvent> r, Net::SocketClient::ErrorCode e)
	{
		if (e == Net::SocketClient::ErrorCode::kSucceed && r->getEvent() == Net::SocketEvent::Event::kConnect)
		{
			std::cout << "Connect succeed! " << r->getInfo() << std::endl;

			auto qlogin = std::make_shared<QLogin>();
			qlogin->uClientId = 11111;
			qlogin->strUsername = "11111";
			qlogin->strPassword = "11111";
			m_socketClient.send(qlogin);
		}
		else
		{
			if (r->getEvent() == Net::SocketEvent::Event::kConnect)
			{
				std::cout << "Connect: "<< r->getInfo() << std::endl;
			}
			else
			{
				std::cout << "DisConnect: " << r->getInfo() << std::endl;
			}
			
		}
	}


	void onUserLogin(std::shared_ptr<RLogin> r, Net::SocketClient::ErrorCode e)
	{
		if (r->strErrorInfo == "LoginSucceed")
		{
			auto qdata = std::make_shared<QData>();
			for (size_t i = 0; i < 10; i++)
			{
				m_socketClient.send(qdata);
			}	
		}
		else if (r->strErrorInfo == "LoginFailure")
		{
			auto qlogin = std::make_shared<QLogin>();
			qlogin->uClientId = 123456;
			qlogin->strUsername = "123456";
			qlogin->strPassword = "123456";
			m_socketClient.send(qlogin);
		}
		
	}

	void onUserData(std::shared_ptr<RData> r, Net::SocketClient::ErrorCode e)
	{
		std::cout << "Nickname: " << r->strNickname << std::endl;
		std::cout << "Sex: " << (r->bSex ? "true": "false") << std::endl;
		std::cout << "Age: " << (int)r->uAge << std::endl;
		std::cout << "Email: " << r->strEmail << std::endl;
		
		for (auto data : r->vData)
		{
			std::cout << "vData: " << data << std::endl;
		}
		
		for (auto data : r->mData)
		{
			std::cout << "vData:" << data.first << ":" << data.second.first << ":" << data.second.second << std::endl;
		}


		std::cout << "customData.nData: " << r->customData.nData << std::endl; 
		std::cout << "customData.fData: " << r->customData.fData << std::endl;
		std::cout << "customData.dData: " << r->customData.dData << std::endl;
		std::cout << "customData.shData: " << r->customData.shData << std::endl;
	}

private:

	Net::SocketClient m_socketClient;
};


int wmain(int argc, wchar_t* argv[])
{
	auto server = Net::SocketServer::createInstance<ServerSocketSession>("127.0.0.1", 6691, 1,true);
	server->registerProtocol(&ServerSocketSession::userLogin);
	server->registerProtocol(&ServerSocketSession::userData);
	
	ClientSocketSession clientSession;


	//一个简单的主循环
	bool bExit(true);
	while (bExit)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(50));

		//在客户端的每一帧需要调用以下函数。
		clientSession.update();
	}


	return 0;
}

  

下面是完整demo,使用vs2013编译

http://files.cnblogs.com/files/winter-yu/libSocket.zip

分享一个自己使用了很久的C++网络封装库,包含服务端和客户端,支持跨平台

标签:

原文地址:http://www.cnblogs.com/winter-yu/p/4688481.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!