package com.mes.service; import com.mes.tools.HexConversion; import com.mes.utils.HexUtil; import io.swagger.models.auth.In; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import static com.mes.tools.HexConversion.*; @Component @Slf4j public class ModbusTcp { //同IP下会有多个协议地址 key=地址区 PlcAgreement为协议内容 plcAgreements为协议组 private Map plcAgreement=new LinkedHashMap(); private String Ip; private int Port; public Socket socket =null;//通讯 public String fileName =""; public ModbusTcp(){} public ModbusTcp(String Ip,int Port,String fileName){ this.Ip=Ip; this.Port=Port; this.fileName=fileName; try { plcAgreement.put(this.fileName,new PlcAgreement(this.fileName)); } catch (Exception e) { log.info("file error:"+this.fileName+",{}",e.getMessage()); } } //连接 public void connect(){ try { this.socket=new Socket(Ip,Port); this.socket.setSoTimeout(1000); }catch (Exception e) { log.info("The IP address of the host cannot be determined:{}",e.getMessage()); } } //关闭连接 public void close(){ try { this.socket.close(); }catch (Exception e) { //log.info("连接关闭异常:{}",e.getMessage()); } } //返回连接状态 public boolean isConnect(){ try { this.socket.isConnected(); }catch (Exception e) { log.info("Connection status exception:{}",this.socket); } return false; } //读取数据 public boolean read(PlcAgreement plcAgreement){ try { if (!this.socket.isConnected()){ // log.info("通讯连接失败:{}",this.socket.isConnected()); return false; } int bufSizes = 0; byte[] msgs = new byte[2048]; byte[] content = new byte[2048]; //写入读取地址 DataOutputStream outToServer = new DataOutputStream(this.socket.getOutputStream()); outToServer.write(HexConversion.stringToInt(plcAgreement.requestHead)); outToServer.flush(); //读取内容 DataInputStream in = new DataInputStream(this.socket.getInputStream()); bufSizes = in.read(msgs); if(bufSizes plcParameters=plcAgreement.getPlcParameters(); for (String key:plcParameters.keySet()){ PlcParameter plcParameter=plcParameters.get(key); if("bit".equals(plcParameter.getType())){ byte font=content[plcParameter.getAddressStart()]; String[] fontBitString=String.format("%8s", Integer.toBinaryString((int)font)).replace(" ", "0").split(""); byte[] bit=new byte[1]; bit[0]=Byte.parseByte(fontBitString[plcParameter.getAddressLength()]); plcParameter.setReadByte(bit); }else{ plcParameter.setReadByte(Arrays.copyOfRange(content,plcParameter.getAddressStart(),(plcParameter.getAddressStart()+plcParameter.getAddressLength()))); } } return true; }catch (Exception e) { //log.info("读取异常:{}",plcAgreement); } return false; } //写入数据 public void write(PlcParameter plcParameter){ try { if (plcParameter.getWriteValue() != null && !"".equals(plcParameter.getWriteValue())) { //写入发送数据 0000 0000 0009 0110 0024 0001 02 0006 byte []sendByte=new byte[13+plcParameter.getAddressLength()]; byte []sendLength=intToBytesDesc(7+plcParameter.getAddressLength(),2); byte []sendAddress=intToBytesDesc(plcParameter.getAddressStart()/2,2); byte []sendFontLength=intToBytesDesc(plcParameter.getAddressLength()/2,2); byte []sendContent=plcParameter.getWriteByte(); //byte []sendContent=intToBytesDesc(Integer.parseInt(plcParameter.getWriteValue().toString()),plcParameter.getAddressLength()); sendByte[4]=sendLength[0]; sendByte[5]=sendLength[1]; sendByte[6]=(byte)1; sendByte[7]=(byte)16; sendByte[8]=sendAddress[0]; sendByte[9]=sendAddress[1]; sendByte[10]=sendFontLength[0]; sendByte[11]=sendFontLength[1]; sendByte[12]=(byte)plcParameter.getAddressLength(); for(int i=0;i14&& addressLength.length>0&& addressLengthFont.length>1&& start.length>1&& content.length>1){ byte head[]=new byte[]{0,0,0,(byte)sendLength,1,16,start[0],start[1],addressLengthFont[0],addressLengthFont[1],addressLength[0],content[0],content[1]}; this.write(head); }else{ log.info("发送内容不符合: 字节长度 {},字长度:{},起始地址,{},内容:{}",addressLength,addressLengthFont,start,content); } } catch (Exception e) { log.info("数据处理异常: 内容 {}",plcParameter); } } //写入数据 public void write(byte []sendByte){ try { if (sendByte != null) { //写入发送数据 DataOutputStream out = new DataOutputStream(this.socket.getOutputStream()); out.write(sendByte); out.flush(); log.info("写入成功: 内容 {}",sendByte); } } catch (Exception e) { log.info("写入失败: 内容 {}",sendByte); } } //写入数据String public void writeString(String sendString,String startAddress){ try { String result=message(sendString,startAddress); if (result != null && !"".equals(result)) { //写入数据 DataOutputStream out = new DataOutputStream(socket.getOutputStream()); out.write(HexUtil.stringToInt(result)); out.flush(); log.info("写入成功:地址 {},内容 {},字节:{}",startAddress,sendString,HexUtil.stringToInt(result)); //this.close(); } } catch (Exception e) { log.info("写入异常:地址 {},内容 {}",startAddress,sendString); } } //写 public String message(String senddate, String address) { String Herd = "0110" + address; int length = senddate.length() / 4; String dates = Herd + HexUtil.intTo2ByteHex(length) + HexUtil.intTo1ByteHex(length * 2) + senddate; int lengths = dates.length() / 2; String date = "00000000" + HexUtil.intTo2ByteHex(lengths) + dates; return date; } public PlcAgreement getPlcAgreement(String key){ return plcAgreement.get(key); } public void consoleLogInfo(PlcAgreement thisPlcAgreement){ String logInfo=this.fileName+" "; Map plcParameterMap=thisPlcAgreement.getPlcParameters(); for (String key:plcParameterMap.keySet()) { logInfo+=key+":"+plcParameterMap.get(key).getValueString()+","; } log.info(logInfo); } }