第三讲:asio通讯之二

上一讲说到了protobuf有关的东西,各位看官记得下载源码,然后把google放进项目中,今天着重关注一下关于消息的hpp文件,直接上代码

#ifndef RECEIVE_MESSAGE_HPP
#define RECEIVE_MESSAGE_HPP

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "cocos2d.h"

#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
    #include "stdint.h"
    #include <WinSock2.h>
#endif

class ReceiveMessage
{
public:
  enum { header_length = 4 };
  enum { cmdid_length = 4 };
  enum { max_body_length = 40960 };

  ReceiveMessage()
    : body_length_(0)
  {
  }

  const char* data() const
  {
    return data_;
  }

  char* data()
  {
    return data_;
  }

  std::size_t length() const
  {
    return header_length + cmdid_length + body_length_;
  }

  const char* body() const
  {
    return data_ + header_length + cmdid_length ;
  }

  char* body()
  {
    return data_ + header_length + cmdid_length ;
  }

  std::size_t body_length() const
  {
    return body_length_;
  }

  void body_length(std::size_t new_length)
  {
    body_length_ = new_length;
    if (body_length_ > max_body_length)
      body_length_ = max_body_length;
  }

  bool decode_cmdid(int32_t *cmdid)
  {
    int32_t cmdid_int32_t ;
    std::memcpy(&cmdid_int32_t, data_ + header_length,cmdid_length);
    *cmdid = htonl(cmdid_int32_t);
    return true;
  }

  bool decode_header(int32_t *cmdid)
  {
    int32_t header_int32_t ;
    std::memcpy(&header_int32_t, data_ ,header_length);
    body_length_ = htonl(header_int32_t);
    decode_cmdid(cmdid);

    if (body_length_ > max_body_length)
    {
      body_length_ = 0;
      return false;
    }
    return true;
  }

private:
  char data_[header_length + cmdid_length + max_body_length];
  std::size_t body_length_;
};

#endif // RECEIVE_MESSAGE_HPP

关于协议,服务器和客户端定了一个简单的通讯协议,在封包的过程中分为3部分,前4个字节代表消息头部,中间4个自己代表消息类型,后面的为消息体

decode_*类型的函数,这连个函数用来转换数据,用来把主机字节序转化为网络字节序

发送的消息协议

//
// AsioSendMessage.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef SEND_MESSAGE_HPP
#define SEND_MESSAGE_HPP

#include <cstdio>
#include <cstdlib>
#include <cstring>

#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "stdint.h"
#include <WinSock2.h>
#endif

#include <asio.hpp>

class AsioSendMessage
{
public:

    std::function< void(int res) > func_sucess;
    std::function< void(asio::error_code ec) > func_fail;

  enum { header_length = 4 };
  enum { max_body_length = 1024 };

  AsioSendMessage()
    : body_length_(0)
  {
      func_sucess = nullptr;
      func_fail = nullptr;
  }

  const char* data() const
  {
    return data_;
  }

  char* data()
  {
    return data_;
  }

  std::size_t length() const
  {
    return header_length + body_length_;
  }

  const char* body() const
  {
    return data_ + header_length;
  }

  char* body()
  {
    return data_ + header_length;
  }

  std::size_t body_length() const
  {
    return body_length_;
  }

  void body_length(std::size_t new_length)
  {
    body_length_ = new_length;
    if (body_length_ > max_body_length)
      body_length_ = max_body_length;
  }

  bool decode_header()
  {
    int32_t header_int32_t ;
    std::memcpy(&header_int32_t, data_ ,header_length);
    body_length_ = htonl(header_int32_t);
    if (body_length_ > max_body_length)
    {
      body_length_ = 0;
      return false;
    }
    return true;
  }

  void encode_header()
  {
    int32_t header_int32_t = htonl(body_length_);
    std::memcpy(data_, &header_int32_t, header_length);
  }

private:
  char data_[header_length + max_body_length];
  std::size_t body_length_;
};

#endif // SEND_MESSAGE_HPP
时间: 11-11

第三讲:asio通讯之二的相关文章

嵌入式OS入门笔记-以RTX为案例:八.RTX的进程间通讯(二)

嵌入式OS入门笔记-以RTX为案例:八.RTX的进程间通讯(二) RTX的进程间通讯主要依赖于四种机制,分别是事件(Event),互斥锁(Mutex),旗语或信号量(Semaphore),和邮箱(Mailbox).前三种机制侧重进程间的同步,邮箱则侧重进程间的数据通讯.这次讲一下信号量和邮箱. 1.信号量(Semaphore) 1.简介 信号量其实是一个很抽象的操作系统原语,它最早由荷兰计算机科学家Dijkstra提 出,用于解决多项资源的分配问题.实际上信号量的适用范围非常广,可以很好地解决很

【IPC进程间通讯之二】管道Pipe

IPC进程间通信+管道Pipe         IPC(Inter-Process Communication,进程间通信).         管道用于进程间共享数据,其实质是共享内存,常用IPC之一.管道不仅可以用于本机进程间通信,还可实现跨网络进程间通信,如同Socket通信,管道同样封装计算机底层网络实现,提供一个良好的API接口.                1.管道(Pipe):        管道分为匿名管道和命名管道.        匿名管道只能用于父子进程间通信 ,不能跨网络通

openfire+asmack搭建的安卓即时通讯(二) 15.4.9

www.meimeidu.com/Theme/Details/150708/www.meimeidu.com/Theme/Details/150707/www.meimeidu.com/Theme/Details/150706/www.meimeidu.com/Theme/Details/150705/www.meimeidu.com/Theme/Details/150704/www.meimeidu.com/Theme/Details/150703/www.meimeidu.com/Theme

operfire+asmack搭建的安卓即时通讯(二) 15.4.9

上期没有放成果图呢!忘了=-=,这就是上次的成果图,textview里面会显示登陆的名字(这个是默认管理员帐号=-=) 好吧,登陆了服务器我们就有了交互的功能啦可以说是前进了一大步呢!下面能我们就要试试从服务器拿一些数据打印出来(服务器定义的群组) 那就开始吧. 首先我另外注册了三个用户来进行测试 还创建了一个组(原谅我起名的无聊) 对了,还要指定共享名字,并把用户加入组成员中! 接着在工具类里面写一个findman()函数用来查找组和打印组: 1 public static void find

controller 和 指令 通讯方法

在 angular 中我们经常会使用多个 controller 和 指令 他们拥有各自的 $scope , 这就产生了跨$scope调用的问题. 有几种常见的方法来可以使用. 方法一 : 指令 require <div directive1="xx"> <div directive2></div> </div> directive("directive1", [function () { return { restri

网络库crash以及boost asio strand dispath分析

最近在做服务器的稳定性的相关测试,服务器的网络底层使用的是boost asio,然后自己做的二次封装以更好的满足需求. 服务器昨天晚上发现crash了一次,之前测试了将近半个多月,有一次是莫名的退出了,不过由于是新的测试服,忘记将ulimit -c进行修改了,所以没有coredump,这次又发生了. coredump如下: #0 0x0000000000000091 in ?? () #1 0x0000000000459729 in ClientHandler::HandleConnect(cp

corosync 实现 MariaDB 数据库服务的高可用

方案: corosync + pacemaker  提供HA的解决方案. 使用NFS共享服务器导出的共享文件系统做为数据目录: 拓扑图如下: 一.配置HA高可用集群的各节点间能够基于主机名通讯. 1.设置主机名 (1).在 192.168.60.128 主机设置 编辑/etc/sysconfig/network文件,使得主机名永久有效 [[email protected] ~]# vim /etc/sysconfig/network HOSTNAME=node2.9527du.com 使用hos

heartbeat v1 实现 MariaDB数据库的高可用

MariaDB数据库服务的高可用: 使用 heartbeat v1 版实现两个节点的 MariaDB数据库服务的高可用. 节点: node1        192.168.60.33 node2        192.168.60.88 MySQL数据库的数据文件使用nfs共享文件系统解决 nfs Server       192.168.60.22 架构如下图: 一.heartbeat 节点之间通信要求的设置: (1).解决节点的主机名解析 因为 heartbeat 的节点间通讯基于名称.基于

华为链路捆绑,Hybrid-VLAN,DHCP,浮动路由,三层交换

综合试验 实验构思图:                              实验要求: 一. VLAN10成员可以和vlan20,30,40的成员通讯,其它vlan则不能互相通讯: 二. 让所以PC都能访问外网AR2: 三. 让PC4能够通过DHCP技术获得IP: 四. AR1和LSW3之间做一个备份链路捆绑: 五. 使用Hybrid-VLAN方法划分VLAN; 六. 让所有PC访问外网时通过13.0网段走,而12.0做为备份链路. 实验步骤: 1.俺图上要求给PC1,2,3配置上相应的I