首页 > 代码库 > 客户端服务端通信protocol
客户端服务端通信protocol
这个协议不知我在上面耗费了多长时间,也有人问过我咋回事,这个protocol不长,但对于我来说理解起来很费劲,今天回来看看忽然看懂了(80%),只能说不知看了多少遍
其实这些东西应该在来的一个月这样子都要会的,一直拖到现在,其实那时时真心看不懂
#ifndef Protocol_Base_H#define Protocol_Base_H//#include <boost/cstdint.hpp>#include <string.h>#pragma pack(push, 1)//-----------基础协议--------------struct Protocol{ unsigned char cmd_type; int size;//content的长度, 不包含本协议头 void* content;//内容的地址 int to_buffer(void* buffer, int buffer_len) { if(!buffer) return -1; //-sizeof(void*)其实这个content没多大作用其实就是标示了一个位置,发送的时候需要将其减去,因为后面直接将内容复制到了这个指针的位置 int total_size = size + sizeof(Protocol) - sizeof(void*); if(buffer_len < total_size) return -1; Protocol* p = (Protocol*)buffer; p->cmd_type = this->cmd_type; p->size = this->size; if (content) { //这句让我理解这个协议费劲了苦头,今天在看终于懂了,也许对c++基础好点的一下就能看懂,我不知看了多少次 //原来看实在不理解这个&p->content,为什么指针还是要取地址,一直在想是指针了还取指针干什么,一直在钻 //其实Protocol* p = (Protocol*)buffer;这个转换可以看下content的值是0,buffer里面存放了指针,然后取指针的地址 //也就是buffer里面这个指针的地址,memcpy将内容复制到指针地址的位置,正好在buffer里面 //包结构(1字节:cmd_type)(4字节:size表示内容的长度)(要发送的内容) memcpy(&p->content, content, size); } return total_size; } bool from_buffer(void* buffer, int len) { if(!buffer) return false; int head_size = sizeof(Protocol) - sizeof(void*); if(len < head_size)//代表空数据 return false; Protocol* p = (Protocol*)buffer; //*this = *p; 长度为5的情况下会出错 this->cmd_type = p->cmd_type; this->size = p->size; if(size) { if(len < head_size + (int)size) { return false; } //这个有点难理解,buffer里面是没有content内容的,个人感觉可以将content理解成一个位置,然后去这个位置的地址,正好是内容的地址 content = &p->content; } return true; }};#pragma pack(pop)#endif //Protocol_Base_H#include <iostream>#include <vector>#include "protocol.h"using namespace std;//模拟放松命令是1,发送一个int 100//发送的时候需要分配一个buffer,然后发送这个buffer,接收的时候需要分配一个buffer,然后从这个buffer里面解析void* g_data = http://www.mamicode.com/new char[100];int g_len;void send(){ void* data = http://www.mamicode.com/new int; *(int*)data = http://www.mamicode.com/100;//数据 int len = 4; //长度 int cmd = 1; //命令 vector<char> buffer; buffer.resize(len + sizeof(Protocol)); Protocol pt = {0}; pt.cmd_type = cmd; pt.content = data; pt.size = len; g_len = pt.to_buffer(&buffer[0], buffer.size());//注意不要&buffer因为buffer是对象在栈上的地址 memcpy(g_data, &buffer[0], g_len);//复制到这个全局的里面方便}void recv(){ Protocol pt = {0}; pt.from_buffer(g_data, g_len); cout << *(int*)pt.content;//这样就可以按照协议发送各种结构体形式的了,这边解析之后强转一下就行了}int main(){ send(); recv(); getchar(); return 0;}
客户端服务端通信protocol
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。