终端参数上报后,平台通过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项目上传到OSS
1.输入阿里云登陆地址 http://signin.aliyun.com/1987179281335458/login.htm 登陆地址 阿里云账号 2.选择对象oss,建议文件夹 3.将文 ...
- 一条sql引发的“血案”
前几天有一个项目要上线,需要对表的一个字段进行扩充,项目经理让我准备脚本,于是我准备了如下的脚本: )); )); )); 结果上线的时候,ord_log1和ord_log2表中有30万数据,在执行的 ...
- 随笔4 Dictionary<K,V>
本来说是想介绍一下Hashtable的,但是发现HashMap和Hashtable最开始的不同就是在于HashMap继承了AbstractMap,而Hashtable继承了Dictionary< ...
- 【LeetCode】未分类(tag里面没有)(共题)
[334]Increasing Triplet Subsequence (2019年2月14日,google tag)(greedy) 给了一个数组 nums,判断是否有三个数字组成子序列,使得子序列 ...
- 解决nginx proxy_pass反向代理cookie,session丢失的问题
参考地址:https://www.jianshu.com/p/34abe7eb6f0b 为什么cookie 会丢失? 比如说一个没有经过代理的地址 : http://127.0.0.1/project ...
- CSS3 Animations
CSS Animations 是CSS的一个模块,它定义了如何用关键帧来随时间推移对CSS属性的值进行动画处理.关键帧动画的行为可以通过指定它们的持续时间,它们的重复次数以及它们如何重复来控制. an ...
- css3 动画 Transition
CSS Transition 1.1 基本用法 在CSS 3引入Transition(过渡)这个概念之前,CSS是没有时间轴的.也就是说,所有的状态变化,都是即时完成. 上面是一个演示,当鼠标放置 ...
- 苹果IOS 12将使您的iPhone更安全,并有更强大的黑客保护
一年一度的IOS刷新正在进行中,苹果已经预览了它,beta测试者已经安装了它,当iPhone在9月份到货时我们其他人应该获得iOS12.虽然软件3-D表情符号和屏幕时间限制等功能在软件到货时可能会受到 ...
- 详解zabbix中文版安装部署
一.zabbix简介(摘自百度百科) zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供柔软 ...
- 对webpack的初步研究3
Output配置output配置选项告诉webpack如何将编译后的文件写入磁盘.请注意,虽然可以有多个entry点,但只output指定了一个配置. A filename to use for th ...