准备工具:

工具下载地址如下:https://github.com/protocolbuffers/protobuf/releases/tag/v3.6.1,主要使用到的文件有:

protoc.exe工具:通过此工具将从自定义的协议文件(.proto)得到相应(.java)的Java类文件;
对应proto.exe版本的protobuf-java.jar包,用于解析上面得到的.java类,这里我使用的是2.5.0版本的protobuf;
chat_send.proto协议文件,关于proto协议文件的书写语法详细的可以查看:Protobuf语言指南,chat_send.proto内容如下(包名package可以根据当前服务器应用的包名进行修改):

//定义使用的protobuf版本
syntax = "proto2";
//定义所在的protobuf包空间
package ares.logic.msg.proto; //生成的java类所在的包路径
option java_package = "ares.logic.msg.proto";
//生成的java类的类名
option java_outer_classname = "ChatSendMsg"; //声明一个message类
message ChatSend{ //(5)
optional int32 mid = 1; // 消息ID, 非必要
required int64 playerid = 3; // 游戏角色ID 必要
required int32 userid = 4; // 用户ID, 必要
required int32 power = 5; // 角色战力值(如果没有可设置为角色等级)
required int32 channel = 6; //消息频道 必要
required string content = 7; //聊天内容 必要
required string playername = 8; // 游戏昵称 必要
required int32 zeusid = 9; // 区服ID 必要
required string ip = 10; // 当前发言人的IP 必要
optional int32 banned = 11; // 是否禁言

cs_enum.proto协议类型枚举文件,用于列举所有协议数据结构的编号:

syntax = "proto2";
//定义所在的protobuf包空间
package ares.logic.msg.proto; //生成的java类所在的包路径
option java_package = "ares.logic.msg.proto";
//生成的java类的类名
option java_outer_classname = "EnmMsgId"; enum EnmCmdId
{
UNIVERSAL = 0;
ChatSend = 1001;//登录请求协议号
}

将.proto转化为Java类文件的处理脚本,这里其实只是一句命令行指令:

protoc  chat_send.proto --java_out=../src/

这里我根据实际项目目录结构定义了一个转文件的.bat批处理文件:

echo on
call protoc --version call protoc chat_send.proto --java_out=../src/
call protoc cs_enum.proto --java_out=../src/
PAUSE

protobuf数据通信过程:

1.客户端创建数据:

要构建一个protobuf数据,需要通过对应协议文件的数据结构,先通过每个数据类型的newBuilder()方法来创建对应的Builder对象,再对Builder中的属性进行赋值,最后才能使用Builder来build()数据对象

public ChatSend getProtobuf() {
     ChatSend.Builder chatBuilder = ChatSend.newBuilder();
   chatBuilder.setMid(EnmCmdId.ChatSend.getNumber());
chatBuilder.setPlayerid(roleId);
chatBuilder.setBanned(banned);
chatBuilder.setChannel(channel);
chatBuilder.setContent(content);
chatBuilder.setIp(loginIp);
chatBuilder.setPlayername(roleName);
chatBuilder.setPower(level);
chatBuilder.setUserid(userId);
chatBuilder.setZeusid(serverId);
return chatBuilder.build();
}

客户端单独启用一个线程,将请求的消息发送给服务器

private void initThread() {
BlockingThreadPool.createThreads(BlockingThreadPool.SkyEye_CHECKER, 1, new SocketHandler());
} private class SocketHandler implements BlockingThreadPool.Callbacker<SkyEyeMsg> {
private boolean retry;
@Override
public void callback(SkyEyeMsg info) {
byte[] data = info.getProtobuf().toByteArray();
try {
if (socket == null) {
initSocket();
}
byte[] len = intToByteArray(data.length);
socket.getOutputStream().write(HEAD);
socket.getOutputStream().write(len);
socket.getOutputStream().write(data);
} catch (Exception e) {
closeSocket(); //socket重连
if(retry){
SkyEyeChecker.logger.error("ckeckMsg Exception :" + e);
}else{
retry = true;
callback(info);
retry = false;
}
}
} byte[] intToByteArray(int len) {
byte[] data = new byte[4];
data[0] = (byte) (len >> 24);
data[1] = (byte) (len >> 16);
data[2] = (byte) (len >> 8);
data[3] = (byte) len;
return data;
}
}

使用Protobuf定义网络协议的更多相关文章

  1. PYTHON黑帽编程1.5 使用WIRESHARK练习网络协议分析

    Python黑帽编程1.5  使用Wireshark练习网络协议分析 1.5.0.1  本系列教程说明 本系列教程,采用的大纲母本为<Understanding Network Hacks At ...

  2. 基础笔记(三):网络协议之Tcp、Http

    目录 一.网络协议 二.TCP(Transmission Control Protocol,传输控制协议) TCP头格式 TCP协议中的三次握手和四次挥手 TCP报文抓取工具 三.HTTP(Hyper ...

  3. 对TCP/IP网络协议的深入浅出归纳

    前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网 ...

  4. linux网络协议

    网络协议 本章节主要介绍linxu网络模型.以及常用的网络协议分析以太网协议.IP协议.TCP协议.UDP协议 一.网络模型 TCP/IP分层模型的四个协议层分别完成以下的功能: 第一层 网络接口层 ...

  5. iOS网络协议 HTTP/TCP/IP浅析

    一.TCP/IP协议       话说两台电脑要通讯就必须遵守共同的规则,就好比两个人要沟通就必须使用共同的语言一样.一个只懂英语的人,和一个只懂中文的人由于没有共同的语言(规则)就没办法沟通.两台电 ...

  6. 转:对TCP/IP网络协议的深入浅出归纳

    转自:http://blog.jobbole.com/74795/ 前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没 ...

  7. linux 网络协议分析---3

    本章节主要介绍linxu网络模型.以及常用的网络协议分析以太网协议.IP协议.TCP协议.UDP协议 一.网络模型 TCP/IP分层模型的四个协议层分别完成以下的功能: 第一层 网络接口层 网络接口层 ...

  8. TFTP网络协议分析---15

    TFTP网络协议分析 周学伟 文档说明:所有函数都依托与两个出口,发送和接收. 1:作为发送时,要完成基于TFTP协议下的文件传输,但前提是知道木的PC机的MAC地址,因为当发送TFTP请求包时必须提 ...

  9. 对TCP/IP网络协议的深入浅出归纳(转)

    前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网 ...

随机推荐

  1. A1098. Insertion or Heap Sort

    According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...

  2. 树结构关系的数据导出为excel

    该文针对的是关于树结构的数据的导出,每一个节点都可以创建不定数的子节点,在选择好某个节点进行导出 时,会把该节点以及子节点的数据都导出来.导出后的excel的格式大概如下图的形式,这个是一个比较理想 ...

  3. codeblocks: 使用静态(static)链接库(pcre)的配置

    说明:在c/c++程序中使用静态链接库,编译后不再需要相关的dll文件(如:libpcre-1.dll,libpcreposix-0.dll)就可以正常的运行. 现在遇到一个问题,如果使用 pcre_ ...

  4. 第二十二节,TensorFlow中RNN实现一些其它知识补充

    一 初始化RNN 上一节中介绍了 通过cell类构建RNN的函数,其中有一个参数initial_state,即cell初始状态参数,TensorFlow中封装了对其初始化的方法. 1.初始化为0 对于 ...

  5. java中异常的面试

    https://blog.csdn.net/qq_36523638/article/details/79363652 1) Java中的检查型异常和非检查型异常有什么区别? 这又是一个非常流行的Jav ...

  6. node(基础)_node.js中的http服务以及模板引擎的渲染

    一.前言 本节的内容主要涉及: 1.node.js中http服务 2.node.js中fs服务 3.node.js中模板引擎的渲染 4.利用上面几点模拟apache服务器 二.知识 1.node.js ...

  7. IO以及file的一些基本方法

    IO定义:将内存的数据 持久化到设备上 这个动作称为输出 写 Output操作 把硬盘上的数据读取到内存 这个动作称为输入 读 Input 把上面这两种操作称为IO操作 File类的静态成员变量:pa ...

  8. mysql5.6安装优化实例

    [client]port = 3306socket = /tmp/mysql.sock[mysqld]log-bin = /data/mysql/bin/mysqlbinlogserver-id = ...

  9. Shell的Posix字符分类

    [:alnum:] 匹配范围为 [a-zA-Z0-9] [:alpha:] 匹配范围为 [a-zA-Z] [:blank:] 匹配范围为 空格和TAB键 [:cntrl:] 匹配控制键 例如 ^M 要 ...

  10. js中的blob,图片base64URL,file之间的关系

    js的base64编码和解码 英文是这样的:// atob() 将base64解码 // btoa() 将字符串转码为base64 var str = 'javascript'; window.bto ...