客户端服务端通信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 = new char[100];
int g_len;
void send()
{
    void* data = new int;
    *(int*)data = 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;
}
时间: 2024-12-28 00:48:52

客户端服务端通信protocol的相关文章

基于Delphi实现客户端服务端通信Demo

在开始之前我们需要了解下这个Demo功能是啥 我们可以看到这是两个小project,左边的project有服务端和客户端1,右边的project只有一个客户端2 效果就是当两个客户端各自分别输入正确的IP地址和PORT端口,然后btconnect连接就可以连接到这个服务端 然后就可以发送消息,服务端的Memo1可以显示来自客户端发送信息的内容. 另外服务端也可以发送消息给两个客户端,做到双向传递信息. 两个客户端发送信息给服务端: 服务端接收消息反馈给客户端: 做的很粗糙,但是大概功能算是实现了

go 客户端服务端通信

client.go package main import ( "bufio" "encoding/json" "fmt" "hash/crc32" "math/rand" "net" "os" // "sync" "time" ) //数据包类型 const ( HEART_BEAT_PACKET = 0x00 REPORT_

netty实现客户端服务端心跳重连

使用netty实现客户端服务端心跳重连 前言: 公司的加密机调度系统一直使用的是http请求调度的方式去调度,但是会出现网络故障导致某个客户端或者服务端断线的情况,导致很多请求信息以及回执信息丢失的情况,接着我们抛弃了http的方式,改为Tcp的方式去建立客户端和服务器之间的连接,并且要去实现断线重连的功能,经过讨论后决定使用java中成熟的nio框架 – netty去解决这一系列的问题. 1.       netty简单介绍: 在百度中对netty的解释是: Netty是由JBOSS提供的一个

Netty入门之客户端与服务端通信(二)

Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码吧. 二.客户端与服务端的通信 2.1 服务端启动程序 public class MyServer { public static void main(String[] args) throws InterruptedException { EventLoopGroup bossGroup = ne

MVC验证10-到底用哪种方式实现客户端服务端双重异步验证

原文:MVC验证10-到底用哪种方式实现客户端服务端双重异步验证 本篇将通过一个案例来体验使用MVC的Ajax.BeginForm或jQuery来实现异步提交,并在客户端和服务端双双获得验证.希望能梳理.归纳出一个MVC异步验证的通用解决思路.本篇主要涉及: 1.通过Ajax.BeginForm()方式,返回部分视图显示验证信息.2.通过jQuery+Html.BeginForm()方式,返回部分视图显示验证信息.3.通过jquery,返回json字符串,json字符串中包含部分视图及验证信息.

vue.js基础知识篇(8):与服务端通信

vue.js可以构建一个完全不依赖后端服务的应用APP,同时也可以与服务端进行数据交互来同步界面的动态更新.vue-resource实现了基于AJAX.JSONP等技术的服务端通信. 第十三章:与服务端通信 1.安装和配置vue-resource 安装方法:使用script标签引入. (1)参数配置.分为全局配置.组件实例配置和调用配置3部分,其优先级依次增高. 第一,全局配置. (2)headers配置 XXX 2.基本HTTP调用 (1)底层方法 (2)便捷方法 (3)请求选项对象 (4)r

Android BLE与终端通信(三)——client与服务端通信过程以及实现数据通信

Android BLE与终端通信(三)--client与服务端通信过程以及实现数据通信 前面的终究仅仅是小知识点.上不了台面,也仅仅能算是起到一个科普的作用.而同步到实际的开发上去,今天就来延续前两篇实现蓝牙主从关系的client和服务端了.本文相关链接须要去google的API上查看,须要FQ的 Bluetooth Low Energy:http://developer.android.com/guide/topics/connectivity/bluetooth-le.html 可是我们依旧

winform 客户端 HTTP协议与服务端通信

本来从来没有仔细研究过Http协议,今天因为公司业务需求,调试了半天,终于现在会Winform用Http协议与服务端通信了,其中常用的有POST和Get方式: 仔细看了人人网和新浪等大部分都是采用GET方式获取数据的,MSN截图如下: 还是不要脱离本文的主要目的: 模拟实现登录代码如下: 1 private void pictureBox3_Click(object sender, EventArgs e) 2 { 3 string strUserName = textEdit1.Text.Tr

警察与小偷的实现之一客户端与服务端通信

来源于ISCC 2012 破解关第四题 目的是通过逆向police,实现一个thief,能够与police进行通信 实际上就是一个RSA加密通信的例子,我们通过自己编写客户端和服务端来实现上面的thief和police的功能.. 要通信,这们这次先通过python写出可以进行网络连接的客户端与服务端.. 服务端代码 #!/usr/bin/env python import SocketServer from time import ctime HOST = '127.0.0.1' PORT =