终端将终端参数以json格式的数据发送至平台。终端上电后上报,可以不认证直接上报。

实现流程如下。

1.设置终端参数上报的协议类型,例如:0x0000。

 public static final int CMD_UP_PARAM = 0x0000;

2.侦听tcp服务

 public void startServer() {
log.info("startServer begin,tcp port={}", port);
//处理接收accept连接的线程池
EventLoopGroup bossGroup = new NioEventLoopGroup();
//处理tcp接收到的数据的线程池
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);// 关键是这句
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws Exception { InetSocketAddress insocket = (InetSocketAddress)ch.localAddress();
// 注册OutboundHandler,执行顺序为注册顺序的逆序
ch.pipeline().addLast(new ProtocolEncoder());
// 注册InboundHandler,执行顺序为注册顺序
//tcp连接始终 120秒 没收到数据 300毫秒未发送数据
ch.pipeline().addLast(new IdleStateHandler(120000, 0, 0, TimeUnit.MILLISECONDS));
//根据不同的侦听端口,采用不同的解码类
ch.pipeline().addLast(new ProtocolDecoder());
ch.pipeline().addLast(new DiffChannelLogin());
ch.pipeline().addLast(new DealProtocolData()); } }).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
log.info("startServer bind,tcp port={}", port);
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
log.error("InterruptedException e={}", e);
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
log.info("startServer end,tcp port={}", port);
}
}

3.处理接收到的tcp数据,该数据是登录认证后的数据。

处理完成后,将结果响应给终端。4位处理代码。

 ProtDataApi diffProtocol(ChnlData chl, ProtDataApi protData) {
if (protData instanceof ProtDataString) {//instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
return diffProtocolString(chl, protData);
} ProtData data = (ProtData) protData;
//log.info("diffProtocol,json={}", data.jsontext);
JSONObject json = JSON.parseObject(data.jsontext);
JSONObject res = null; if (data.getCmd() == DeviceProtCmd.CMD_UP_LOGIN) {
res = service.logIn(chl, json);
if (res == null) {
chl.close();
return null;
}
} else if(data.getCmd() == DeviceProtCmd.CMD_UP_PARAM){ } else if (chl.getData() instanceof DeviceData == false){
chl.close();
return null;
} long context = json.getLongValue("context");
if (context > 0) { } taskDao.recvDevTaskData(data.getCmd(), json); DeviceData dev = (DeviceData) chl.getData();
if (dev != null) {
ProtDataApi d = dao.updateTaskFlag(dev.getId(), json);
if (d != null) {
return d;
}
}
switch (data.getCmd()) {
case DeviceProtCmd.CMD_UP_PARAM:
res = service.uploadParam(chl, json);
break;
default:
break;
} if (res == null) {
return null;
} return new ProtData(data.getCmd(), data.getSessionId(), res.toJSONString(), chl.getEncoding());
}

4.平台处理接收到的终端参数,并更新入库,响应结果。

public JSONObject uploadParam(JSONObject json) throws Exception {
String identity = json.getString("identity");// ”:”设备序列号”,
int id = dataDao.getDeviceId(identity);
if (id == -1) {
log.error("该设备,identity={},不存在!", identity);
return JsonUtils.getErrorJson(ErrorCode.ERR_NORECORD);
} String modelno = json.getString("modelno");//":"KCC(1A)", //设备型号
String devtype = json.getString("devtype");//":"1011", //设备类型
String hardver = json.getString("hardver");//":"硬件版本",
String softver = json.getString("softver");//":"软件版本",
String serverip = json.getString("serverip");//":"平台ip",
String serverport = json.getString("serverport");//":"平台端口号",
String sql = "update info_terminal set devModel=?,devicetypeid=?,hardver=?"
+ ",softver=?,platform_ip=?,platform_port=? where id=?";
JSONObject res;
try {
jt.update(sql, modelno,devtype,hardver,softver,serverip,serverport,id);
res = JsonUtils.getErrorJson(ErrorCode.ERR_SUCCESS);
} catch (DataAccessException e) {
log.error("更新参数失败,sql={},json={},exception={}", sql, json.toJSONString(), e);
res = JsonUtils.getErrorJson(ErrorCode.ERR_SAVE);
}
return res;
}

5.回应终端数据处理

 public short head;//协议头
public int cmd;//协议类型
public int sessID;//会话id
public short pkgID;//包号
public short pkgCount;//总包数
public short keyID;//密钥id
public short datalen;//单包数据长途
public int totalLen;//数据总长度
public byte[] data;//数据
private ChannelHandlerContext ctx;
public String jsontext;//json字符串
private String encoding; public ProtData(int cmd, int sessID, String jsontext, String encoding){
this.encoding = encoding;
this.head = 0x2324;
this.cmd = cmd; this.sessID = sessID;
pkgCount = 1;
pkgID = 0;
keyID = (short) DeskeyConfig.getKeyId();
datalen = 0;
data = new byte[datalen];
DecryptionMode jm = DecryptionMode3DesImp.getDecryptionMode();
data = jm.getDecryption(data, sessID, keyID);
this.jsontext = jsontext;
}

6.附上协议。

json格式如下:
{
"identity":"设备序列号",
"modelno":"kcc(1a)", //设备型号
"devtype":1011, //设备类型
"hardver":"硬件版本",
"softver":"软件版本",
"serverip":"平台ip",
"serverport":平台端口号
}
应答:
字段名 长度 备注
json n json格式的数据 json格式如下:
{
"errcode":错误码
}

终端参数上报后,平台通过tcp协议接收到相应数据并处理。的更多相关文章

  1. 【转】使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?

    使用TCP协议连续传输大量数据时,是否会丢包,应如何避免? 比如发送文件.记得有人提过可能会发生什么堆栈溢出.怎样避免呢?是不是可以收到数据后发送确认包,收到确认包后再继续发送.或是发送方发送了一些数 ...

  2. 【Java】学习路径60-利用TCP协议接收多个客户端的数据

    import java.io.IOException; import java.net.*; public class TCP_Server { public static void main(Str ...

  3. Python3的tcp socket接收不定长数据包接收到的数据不全。

    Python Socket API参考出处:http://blog.csdn.net/xiangpingli/article/details/47706707 使用socket.recv(pack_l ...

  4. java-UDP协议接收和发送数据

    UDP发送数据的步骤: A:创建发送端的Socket服务对象 B:创建数据,并把数据打包 C:通过Socket对象的发送功能发送数据包 D:释放资源 public class SendDemo {   ...

  5. (Tcp协议)linux上netstat -atunlp后出现的数据的意思(socket状态)

    https://zhidao.baidu.com/question/486077599.html 1.netstat命令的-t参数指的是 tcp的简写,意思是仅显示tcp相关选项2.示例:列出所有 t ...

  6. (2)socket的基础使用(基于TCP协议)

    socket()模块函数用法 基于TCP协议的套接字程序 netstart -an | findstr 8080 #查看所有TCP和UDP协议的状态,用findstr进行过滤监听8080端口 服务端套 ...

  7. 【TCP协议详解】

    为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样 ...

  8. Linux 高性能服务器编程——TCP协议详解

    问题聚焦:     本节从如下四个方面讨论TCP协议:     TCP头部信息:指定通信的源端端口号.目的端端口号.管理TCP连接,控制两个方向的数据流     TCP状态转移过程:TCP连接的任意一 ...

  9. 【转】运输层TCP协议详细介绍

    TCP是TCP/IP协议族中非常复杂的一个协议.它具有以下特点: 1:面向连接的运输层协议.在使用TCP协议之前,首先需要建立TCP连接.传送数据完毕后,必须释放已经建立的TCP连接. 2:一条TCP ...

随机推荐

  1. Malware分析

    //文章来源:http://www.2cto.com/Article/201312/265217.html by Kungen@CyberSword 想要查找恶意样本,首先要知道查找样本所需的基本信息 ...

  2. python编程基础之简单购物车

    #good文件夹内容[ ['Iphone7', 5800], ['Coffee', 30], ['疙瘩汤', 10], ['Python Book', 99], ['Bike', 199], ['Vi ...

  3. vue 和react中子组件分别如何向父组件传值

    vue子组件和父组件双向传值: 子: Vue.component("childComponent",{ template:`<div><p @click='pos ...

  4. ideamaven版的MBG逆向工程

    一.简介 简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的根据表生成对应的映射文件,接口,以及bean类. 支持基本的增删改查,以及QBC风格的条件查询. 但是表连接.存储 ...

  5. linux 服务器与客户端异常断开连接问题

    服务器与客户端连接,客户端异常断掉之后服务器端口仍然被占用, 到最后是不是服务器端达到最大连接数就没法连接了?领导让我测试这种情况,我用自己的电脑当TCP Client,虚拟机当服务器,连接之后能正常 ...

  6. Centos7搭建日志服务器rsyslog+loganalyzer

    一.系统环境 Rsyslog Server OS:CentOS 7 Rsyslog Server IP:172.28.194.118 Rsyslog Version: rsyslog-7.4.7-12 ...

  7. cat 合并文件或查看文件内容

    1.命令功能 cat 合并文件或者查看文件内容. 2.语法格式 cat   option    file 参数说明 参数 参数说明 -n 打印文本,并显示每行行号并且空白行也同样包括 -b 与-n用法 ...

  8. Windows系统中,循环运行.bat/.exe等文件

    一.创建循环运行的run-everySecond.vbs文件[双击次文件即可启动运行] dim a set a=CreateObject("Wscript.Shell") Do # ...

  9. Redis分布式锁【正确实现方式】

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  10. php io

    1.获取目录下文件,不包括子目录 //获取某目录下所有文件.目录名(不包括子目录下文件.目录名) $handler = opendir($dir); while (($filename = readd ...