最近一直在做java串口方面的程序,实现java软件与下位机的通信。但是下位机速度比电脑慢的多,导致从java程序中每次只能读出几个字节的数据,不能够形成完整的数据帧。所以做一个程序来打包串口的数据。

    二者通信的数据格式为:帧头+标志位+数据位+帧尾。例如,帧头为@,帧尾为#,数据位为5位,一位标志位,则通信的数据为“@X01010#”。java必须能从一串数据中检索出数据帧,并且能够把不完整的数据帧拼接成完整的数据帧。例如从“ASDASD5@X01010#AD”准确地检索出所需要的数据帧,或者把“@X0101”和“0#”拼接成一个完整的数据帧。下面我把程序的流程图附上。

wKioL1SBeRSyzS5vAAQUc15qZzw821.jpg

下面为java代码:

    public void packData(byte[] indata,int inlength)
	{
		int cursor=0;
		if(!isstart)
		for(int i=0;i<inlength;i++)  //判断是否报包含帧开始头
		{
			if(indata[i]==START)
			{
				cursor=i;
				isstart=true;
				break;
			}
		}
		if(isstart)           //开始分析打包数据
		{
			
			for(int i=cursor;i<inlength;i++)   //计算数据中有几个帧头
			{
				if(indata[i]==START)
					start++;
			}
			for(int i=cursor;i<inlength;i++)  //复制数据到data[],并判断帧头帧尾数量是否相同
			{
				data[length+i-cursor]=indata[i];
				if(indata[i]==END)
					end++;
				if(end==start)    //帧头帧尾数量相同,结束循环,丢弃之后的数据,更新数据长度
				{
					length+=i-cursor+1;
					break;
				}
				if(length>100)  //当数据长度大于1000的时候,丢弃所有的数据,重新开始
				{
					start=0;
					end=0;
					length=0;
					isstart=false;
					return;
				}
				
			}
			if(start>end)  //帧头帧尾数量不同,更新数据长度,等待下一包数据
				length+=inlength-cursor;
			else if(start<end)
				System.out.println("start<end");
			else if (start==end)  //数量相同,开始对数据进行解析
			{
				final int frame=start;
				final int framelen=length/frame;
				start=0;
				end=0;
				length=0;
				isstart=false;
				for(int i=0;i<frame;i++)
				{
					byte[] buff=new byte[framelen];
					System.arraycopy(data, i*framelen, buff, 0, framelen);
					DataAutoPro(buff, framelen);
					System.out.println(new String(buff, 0, framelen));
				
				}
			}
				
		}
			
	}