终端参数上报后,平台通过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 ...
随机推荐
- win7 开启 telnet 服务
如何重新开启win7的telnet服务 “控制面板”-->“系统和安全”-->“允许远程访问”-->“远程桌面”-->“选择用户”,添加可telnet的用户. “控制面板”-- ...
- basename函数不能获取url路径中文文件名的问题
basename basename() 函数返回路径中的文件名部分. 语法 basename(path,suffix) 参数 描述 path 必需.规定要检查的路径. suffix 可选.规定文件扩展 ...
- JavaScript基础3——使用Button提交表单
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Windows10测试低版本IE方法
前端开发工程师可能了解IETester是一款IE多版本兼容性测试软件,但是只支持Windows Xp,Vista,7,8系统,Windows10是不支持的,网上所说的开启.net framework ...
- Jquery Ajax简单封装(集中错误、请求loading处理)
Jquery Ajax简单封装(集中错误.请求loading处理) 对Jquery Ajax做了简单封装,错误处理,请求loading等,运用到项目中集中处理会很方便. 技术层面没有什么好说的,请求是 ...
- 【LeetCode】二分 binary_search(共58题)
[4]Median of Two Sorted Arrays [29]Divide Two Integers [33]Search in Rotated Sorted Array [34]Find F ...
- 二、MyBatis-HelloWorld
环境准备 1.创建数据库表 create table tbl_employee ( id ) primary key AUTO_INCREMENT comment "ID", la ...
- POJ-1390-Blocks (复杂区间DP)
$ POJ~1390~~Blocks: $ (很难想的区间DP) $ solution: $ 很好的一道题目.看起来似乎很简单,当时一直认为可以用二维区间DP来完成,转移 $ n^3 $ . 后来发现 ...
- phpstorm 调试时浏览器显示The requested resource / was not found on this server
1.进入thinkphp项目的public 目录运行以下命令即可 root@jiang:/var/www/tp5# php -S localhost:8080 router.php PHP 7.2.2 ...
- simulate 中的一些操作
1. neutralize: position based 的alpha int neutralize(int di, int ti) { ; ; ; ; ii < nsyms; ++ii) { ...