使用Protobuf定义网络协议
准备工具:
工具下载地址如下: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定义网络协议的更多相关文章
- PYTHON黑帽编程1.5 使用WIRESHARK练习网络协议分析
Python黑帽编程1.5 使用Wireshark练习网络协议分析 1.5.0.1 本系列教程说明 本系列教程,采用的大纲母本为<Understanding Network Hacks At ...
- 基础笔记(三):网络协议之Tcp、Http
目录 一.网络协议 二.TCP(Transmission Control Protocol,传输控制协议) TCP头格式 TCP协议中的三次握手和四次挥手 TCP报文抓取工具 三.HTTP(Hyper ...
- 对TCP/IP网络协议的深入浅出归纳
前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网 ...
- linux网络协议
网络协议 本章节主要介绍linxu网络模型.以及常用的网络协议分析以太网协议.IP协议.TCP协议.UDP协议 一.网络模型 TCP/IP分层模型的四个协议层分别完成以下的功能: 第一层 网络接口层 ...
- iOS网络协议 HTTP/TCP/IP浅析
一.TCP/IP协议 话说两台电脑要通讯就必须遵守共同的规则,就好比两个人要沟通就必须使用共同的语言一样.一个只懂英语的人,和一个只懂中文的人由于没有共同的语言(规则)就没办法沟通.两台电 ...
- 转:对TCP/IP网络协议的深入浅出归纳
转自:http://blog.jobbole.com/74795/ 前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没 ...
- linux 网络协议分析---3
本章节主要介绍linxu网络模型.以及常用的网络协议分析以太网协议.IP协议.TCP协议.UDP协议 一.网络模型 TCP/IP分层模型的四个协议层分别完成以下的功能: 第一层 网络接口层 网络接口层 ...
- TFTP网络协议分析---15
TFTP网络协议分析 周学伟 文档说明:所有函数都依托与两个出口,发送和接收. 1:作为发送时,要完成基于TFTP协议下的文件传输,但前提是知道木的PC机的MAC地址,因为当发送TFTP请求包时必须提 ...
- 对TCP/IP网络协议的深入浅出归纳(转)
前段时间做了一个开发,涉及到网络编程,开发过程比较顺利,但任务完成后始终觉得有一些疑惑.主要是因为对网络协议不太熟悉,对一些概念也没弄清楚.后来 我花了一些时间去了解这些网络协议,现在对TCP/IP网 ...
随机推荐
- 【SPOJ10707】COT2 - Count on a tree II
题目大意:给定一棵 N 个节点的无根树,每个节点有一个颜色.现有 M 个询问,每次询问一条树链上的不同颜色数. 题解:学会了树上莫队. 树上莫队是将节点按照欧拉序进行排序,将树上问题转化成序列上的问题 ...
- @Async的简单用法总结
前言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时 候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3 ...
- 一文看懂npm、yarn、pnpm之间的区别
文作者对比了当前主流的包管理工具npm.yarn.pnpm之间的区别,并提出了合适的使用建议,以下为译文: NPM npm是Node.js能够如此成功的主要原因之一.npm团队做了很多的工作,以确保n ...
- 有趣的js获取input标签中光标的索引
先看动图如下,我们就可以很清楚的知道获取input标签中光标的索引的意思了. 由于IE支持document.selection,Firefox,Chrome,Safari以及Opera都有select ...
- P NP NPC
study from : http://www.matrix67.com/blog/archives/105
- __int128
__int128 __uint128 __int128_t __uint128_t 大小:16字节 2^128(sizeof()) 2^128 39位 340282366920938463463374 ...
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊(分块算法)
传送门 题意: 中文题意,不再赘述. 题解: 下午在补分块算法的相关知识,看到某大神博客推荐的这道题目,就试着做了做: TLE了一下午可还行: 我的思路: 将这 n 个点分成 sqrt(n) 块: i ...
- Unity 网络编程(Socket)应用
服务器端的整体思路: 1.初始化IP地址和端口号以及套接字等字段: 2.绑定IP启动服务器,开始监听消息 socketServer.Listen(10): 3.开启一个后台线程接受客户端的连接 so ...
- JS学习笔记Day5
一.变量的作用域 1.作用域:变量的作用范围 2.全局变量:变量在整个程序都是有效的(从程序开始到程序结束变量均有效)在函数体外部定义的变量都是全局变量:在函数体内部 没有用var定义的变量也有可能是 ...
- ngnix FastCGI解析漏洞
漏洞描述: Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME.当访问http://192.168.1.103/phpin ...