终端参数上报后,平台通过tcp协议接收到相应数据并处理。
终端将终端参数以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协议接收到相应数据并处理。的更多相关文章
- 【转】使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
使用TCP协议连续传输大量数据时,是否会丢包,应如何避免? 比如发送文件.记得有人提过可能会发生什么堆栈溢出.怎样避免呢?是不是可以收到数据后发送确认包,收到确认包后再继续发送.或是发送方发送了一些数 ...
- 【Java】学习路径60-利用TCP协议接收多个客户端的数据
import java.io.IOException; import java.net.*; public class TCP_Server { public static void main(Str ...
- Python3的tcp socket接收不定长数据包接收到的数据不全。
Python Socket API参考出处:http://blog.csdn.net/xiangpingli/article/details/47706707 使用socket.recv(pack_l ...
- java-UDP协议接收和发送数据
UDP发送数据的步骤: A:创建发送端的Socket服务对象 B:创建数据,并把数据打包 C:通过Socket对象的发送功能发送数据包 D:释放资源 public class SendDemo { ...
- (Tcp协议)linux上netstat -atunlp后出现的数据的意思(socket状态)
https://zhidao.baidu.com/question/486077599.html 1.netstat命令的-t参数指的是 tcp的简写,意思是仅显示tcp相关选项2.示例:列出所有 t ...
- (2)socket的基础使用(基于TCP协议)
socket()模块函数用法 基于TCP协议的套接字程序 netstart -an | findstr 8080 #查看所有TCP和UDP协议的状态,用findstr进行过滤监听8080端口 服务端套 ...
- 【TCP协议详解】
为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样 ...
- Linux 高性能服务器编程——TCP协议详解
问题聚焦: 本节从如下四个方面讨论TCP协议: TCP头部信息:指定通信的源端端口号.目的端端口号.管理TCP连接,控制两个方向的数据流 TCP状态转移过程:TCP连接的任意一 ...
- 【转】运输层TCP协议详细介绍
TCP是TCP/IP协议族中非常复杂的一个协议.它具有以下特点: 1:面向连接的运输层协议.在使用TCP协议之前,首先需要建立TCP连接.传送数据完毕后,必须释放已经建立的TCP连接. 2:一条TCP ...
随机推荐
- 初入vue.js(1)
本文章属于个人在学习vue的随笔,留作与大家分享,技术交流之用,如果有错误,请大家多多指正.谢谢 首先说一下vue的使用方式: vue的使用方式一共有两种,第一种是直接在官网上下载vue.js的文件, ...
- 剑指offer--字符串
C/C++中每个字符串都以字符'\0'作为结尾,这样我们就可以很方便的找到字符串最后的尾部.由于这个特点,每个字符串中都有一个额外字符的开销,稍不留神就会造成字符串的越界. 为了节省内存,C/C++把 ...
- Python之路-pandas包的详解与使用
什么是pandas pandas是一种Python数据分析的利器,是一个开源的数据分析包,最初是应用于金融数据分析工具而开发出来的,因此pandas为时间序列分析提供了很好的支持.pandas是PyD ...
- 微信小程序之全局储存
全局变量app.globalData 本地缓存wx.setStorageSync(KEY,DATA)wx.getStorageSync(KEY)wx.getStorageInfoSyncwx.remo ...
- CA认证机制的简明解释
公钥机制面临的问题: 假冒身份发布公钥! 可以用CA来认证公钥的身份.CA有点像公安局,公钥就像身份证.公安局可以向任何合法用户颁发身份证以证明其合法身份.第三方只要识别身份证的真伪就能判断身份证持有 ...
- 揭示编译器API
编译器管道功能区 .NET编译器平台(“Roslyn”)通过提供一个API层,是一个传统编译器管道镜像,向你这样的消费者揭示了C#和Visual Basic编译器的代码分析. 这条管道的每一部分,现在 ...
- CSS3 多列布局——Columns
CSS3 多列布局——Columns 语法: columns:<column-width> || <column-count> 多列布局columns属性参数主要就两个属性参数 ...
- 学习python os commands socket模块
import os print(os.getcwd()) #获取当前路径, 导包也是从这个路径下面才能找到 # os.chdir('./..') #返回上一级路径,再获取路径看看 # print(os ...
- 美国的科技公司是如何使用加密的DNS
加密设备和“以隐私为中心”的提供商之间的DNS流量可以阻止某人窥探您的浏览器所指向的位置,或者使用DNS攻击将其发送到其他地方. 该网络中立性的死亡和法规对互联网服务供应商如何处理客户的网络流量的松动 ...
- [洛谷 P1013] NOIP1998 提高组 进制位
问题描述 著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字. 例如: L K V E L L K V E K K V E KL V V E KL KK E E K ...