java实现JT809协议数据对接客户端

本文详细介绍了使用Java实现JT809协议进行TCP客户端数据对接的过程,包括TCP连接、登录、心跳处理、解码、消息处理等关键步骤。遇到的主要挑战包括CRC校验、数据转义、不同长度的反馈信息处理等,同时提供了代码示例。文章还提及了多服务器推送数据时的账号管理,并给出了JT/T415-2006标准协议中车牌颜色的对应状态。
摘要由CSDN通过智能技术生成

最近使用JT809协议进行数据对接,遇到了不少问题,度娘谷歌都不好使,找不到很好的客户端实现代码的例子,只能苦逼的自己闷头弄,现在特意写篇帖子,希望能帮助一些人

说正经的:

背景:跟某公司做数据对接,将本公司的一些信息推送到接收端

要求:建立tcp链接,使用接收端提供的用户名密码等信息 先登录,登录成功后推送数据,数据采用JT809标准协议

实现语言:java

下面介绍具体实现,包涵完整代码

在这之前,最好先下载jt809协议,研究研究,网上就有,我找到的里面还有一些错误别,一度让我觉得是个盗版货

首先说下整体结构:一个tcp客户端,一个Decoder,一个心跳Handler,一个处理反馈的handler,一个消息对象

通过tcp客户端链接制定ip地址和端口,进行登陆,心跳handler负责在发送数据空闲时向目标服务器发送请求保持包;decoder负责解码组装对象,反馈handler负责处理收到的反馈信息,消息对象我就不多说了

下面看代码:

TCPclient:

由于时间紧迫,代码结构有些臃肿,我使用的tcpclient为两个,一个是基类,一个子类,其实这两个可以合并到一起,这里有心的朋友自己去和,下面来看下tcpclient基类的代码,其中有一些模块的引用因为涉及到公司信息,所以我删除掉了,大家参考的时候,引用自己编写的就可以了,

 

//包路径,自己填
import java.net.InetSocketAddress;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.logging.LoggingHandler;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.logging.InternalLogLevel;
import org.jboss.netty.util.HashedWheelTimer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



public class TcpClient{

	private static final Logger LOG = LoggerFactory.getLogger(TcpClient.class);

	private static final int DEFAULT_PORT = 9000;

	private long connectTimeoutMillis = 3000;

	private int port = DEFAULT_PORT;

	private boolean tcpNoDelay = false;

	private boolean reuseAddress = true;

	private boolean keepAlive = true;

	private int workerCount = 4;

	private ClientBootstrap bootstrap = null;
	
	private  static Channel channel = null;

	private Executor bossExecutor = Executors.newCachedThreadPool();

	private Executor workerExecutor = Executors.newCachedThreadPool();
	

	private static TcpClient instance = new TcpClient();

	private TcpClient() {
		init();
	}
	
	public static TcpClient getInstence(){
		return instance;
	}

	
	public void init() {

		bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(
				bossExecutor, workerExecutor, workerCount));
		bootstrap.setOption("tcpNoDelay", tcpNoDelay);
		bootstrap.setOption("connectTimeoutMillis", connectTimeoutMillis);
		bootstrap.setOption("reuseAddress", reuseAddress);
		bootstrap.setOption("keepAlive", keepAlive);
	}
	
	
	public Channel getChannel(String address, int port) {
		
		if (null == channel || !channel.isOpen()) {
			bootstrap.setOption("writeBufferHighWaterMark", 64 * 1024);
			bootstrap.setOption("writeBufferLowWaterMark", 32 * 1024);
			bootstrap.setPipelineFactory(new ChannelPipelineFactory(){
				@Override
				public ChannelPipeline getPipeline() throws Exception {
					ChannelPipeline pipeline = Channels.pipeline();
//					pipeline.addLast("loging", new LoggingHandler(InternalLogLevel.ERROR)); 打印日志信息,上线稳定后可去掉
					pipeline.addLast("timeout", new IdleStateHandler(new HashedWheelTimer(), 10, 60, 0));//设置空闲心跳机制
					pipeline.addLast("heartbeat", new HeartBeatHandler());//心跳发送包处理handler
					pipeline.addLast("decode", new Decoder());//解码
					pipeline.addLast("loginHandler", new RecevieHandler());//反馈数据处理
					return pipeline;
				}
			});
			ChannelFuture future = bootstrap.connect(new InetSocketAddress(
					address, port));
			future.awaitUninterruptibly();
			if (future.isSuccess()) {
				channel = future.getChannel();
			} else {
				throw new FrameworkRuntimeException(future.getCause());
			}
		}

		return channel;
	}

	

	public long getConnectTimeoutMillis() {
		return connectTimeoutMillis;
	}

	public void setConnectTimeoutMillis(long connectTimeoutMillis) {
		this.connectTimeoutMillis = connectTimeoutMillis;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public boolean isTcpNoDelay() {
		return tcpNoDelay;
	}

	public void setTcpNoDelay(boolean tcpNoDelay) {
		this.tcpNoDelay = tcpNoDelay;
	}

	public boolean isReuseAddress() {
		return reuseAddress;
	}

	public void setReuseAddress(boolean reuseAddress) {
		this.reuseAddress = reuseAddress;
	}

	public boolean isKeepAlive() {
		return keepAlive;
	}

	public void setKeepAlive(boolean keepAlive) {
		this.keepAlive = keepAlive;
	}

	public int getWorkerCount() {
		return workerCount;
	}

	public void setWorkerCount(int workerCount) {
		this.workerCount = workerCount;
	}
	
}

 

上面的配置,用过netty都不会陌生,就不多说了,下面看下子类的实现

 



import java.nio.charset.Charset;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Cha
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fox_mt

真的帮助了你,而你又签好有钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值