终端将终端参数以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. 搭建Eclipse+pydev+python2.7.5+django1.5.1+mysql5.0.45平台

    mysqldb 下载地址 http://sourceforge.net/projects/mysql-python/ or https://pypi.python.org/pypi/MySQL-pyt ...

  2. mysql考试复习

    基础创建 字段自动编号auto_increment ( 单词补充:increment 定期的加薪; 增量; 增加) 考点 添加自增 alter table [表名] modify [字段(id)] i ...

  3. 解决Vuex刷新页面数据丢失问题 ---- vuex-persistedstate持久化数据

    何为Vuex?用处是什么?为什么刷新丢失? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 ...

  4. linux Sersync 上配置客户端

    1.安装 Rsync 并配置相关权限 在 SERSYNC 上配置 RSYNC 客户端相关权限认证: [root@SERSYNC /]# yum install rsync -y [root@SERSY ...

  5. PyQt5+qtdesigner开发环境配置

    1.PyQt5安装 pip install PyQt5 2.qtdesigner安装 本来直接用pip install PyQt5-tools安装的,但是网速下的慢,中间还断了几次,在网上找到一个稳定 ...

  6. Linux根据进程号查找其程序文件路径 及 lsof 命令使用

    查找进程文件路径 lsof -p pid 1.列出所有打开的文件: lsof 备注: 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位 2. 查看谁正在使用某个文件 lsof   ...

  7. 18 StringBuilder类型有何作用

  8. C++创建对象时什么时候用*,什么时候不用*

    用*, 表示创建的是一个指针对象,而指针的创建,必须初始化,C++中用new关键字开辟内存. 另外指针对象访问成员变量用-> , 非指针用. 就这么个原则 但是指针也可以不用-> 例如 ( ...

  9. vim 批量添加删除注释

    vim中单行注释只是多行注释的一个特例,这里统一进行多行注释的讲解 (1)添加批量注释 ctrl+v 进入列编辑模式,向下或向上移动光标,把需要注释的行的开头标记起来,然后按大写的I(shift+i) ...

  10. python&数据分析&数据挖掘--参考资料推荐书籍

    1.要用python做数据分析,先得对python语言熟悉,推荐一本入门书 :笨方法学python (learn python the hard way),这本书用非常有趣的讲述方式介绍了python ...