最近写软件用到了socket通信,然后各种查东西把代码写好了,其逻辑是我从软件后台向终端发送一条十六进制的字符串,然后终端收到之后给我回复,我再将收到的信息进行读取解析,将收到的信息发送到前台显示。
代码:
Controller控制层
@Controller
@RequestMapping(value = "${adminPath}/socket/socket")
public class SocketController extends BaseController{
private static final Logger logger = LoggerFactory.getLogger(SocketController.class);
@Autowired
private SocketService socketService;
@Autowired
private MornitorInitService mornitorInitService;
/**
* 查询节点温度状况,查询节点电量状况
* 查询节点信息
* @return
* @throws IOException
*/
@RequestMapping(value = {"getNodeInfo"})
@ResponseBody
public String getNodeInfo(HttpServletRequest request,HttpServletResponse response, Model model) throws IOException{
//获取前台参数 作业面编号
String constructionSideId = request.getParameter("constructionSideId");
//通过作业面编号查询作业面信息
ConstructionSide side = mornitorInitService.queryConstructionSide(constructionSideId);
//通过作业面编号查询作业面设备,人员,管道信息
List<ConstructionEquipment> equipmentList = mornitorInitService.findEquipment(side.getId());
List<ConstructionPerson> personList=mornitorInitService.queryPerson(side.getId());
List<PipeInfo> pipeList=mornitorInitService.findAll(side.getId());
//查询电量温度时向终端发送的信号
String str="7A7701010000011711160000010402000101";
StringBuilder sb = new StringBuilder("");
String h="";String h1 = "";
//查询作业面内车子定位节点的温度和电量
for(ConstructionEquipment equipment:equipmentList) {
String ip=equipment.getMasterLabelIp();
String ip1=equipment.getSlaveLabelIp();
if(ip!=null) {
String info=socketService.getSocket(ip, str);
if(info!=null|info!="") {
String[] infos = info.split(",");
int a = Integer.parseInt(infos[0]);
int a1 = Integer.parseInt(infos[1]);
if(a>60&a1<30) {
h="设备"+equipment.getCode()+"的节点"+equipment.getMasterSn()+"的温度超标,当前为"+a+"摄氏度并且电量过低,当前为"+a1+"%,请及时更换节点;";
}else {
if(a>60) {
h="设备"+equipment.getCode()+"的节点"+equipment.getMasterSn()+"的温度超标,当前为"+a+"摄氏度,请及时更换;";
}
if(a1<30) {
h="设备"+equipment.getCode()+"的节点"+equipment.getMasterSn()+"的电量过低,当前为"+a+"%,请及时更换;";
}
}
sb.append(h);
}
}
if(ip1!=null) {
String info1=socketService.getSocket(ip1, str);
if(info1!=null|info1!="") {
String[] info1s = info1.split(",");
int a3 = Integer.parseInt(info1s[0]);
int a4 = Integer.parseInt(info1s[1]);
if(a3>60&a4<30) {
h1="设备"+equipment.getCode()+"的节点"+equipment.getSlaveSn()+"的温度超标,当前为"+a3+"摄氏度并且电量过低,当前为"+a4+"%,请及时更换节点;";
}else {
if(a3>60) {
h1="设备"+equipment.getCode()+"的节点"+equipment.getSlaveSn()+"的温度超标,当前为"+a3+"摄氏度,请及时更换;";
}
if(a4<30) {
h1="设备"+equipment.getCode()+"的节点"+equipment.getSlaveSn()+"的电量过低,当前为"+a4+"%,请及时更换;";
}
}
}
sb.append(h1);
}
}
//查询作业面内管道定位节点的温度和电量
String strs=sb.toString();
model.addAttribute("strs", strs);
return renderString(response, model);
}
}
Service服务层
@Service
public class SocketService {
/**
* 用于发送温度电量请求信息 且接受响应回复信息
* @param ip
* @param str
* @return
* @throws IOException
*/
public String getSocket(String ip,String str) throws IOException{
//socket信号发送 字符转化16进制
//开启socket连接
Socket socket=new Socket(ip,8899);
//输出流
OutputStream os=socket.getOutputStream();
//将字符转化为字节
byte[] n=hexStrToBinaryStr(str);
//获取验证码
String str1=getCRC(n);
//将验证码拼接在字符串后边
String str2=str+str1;
//将完整的需要传输的字符串转化为字节数组
byte[] n1=hexStrToBinaryStr(str2);
//传输
os.write(n1);
//创建接受信息
InputStream is=socket.getInputStream();
byte b1[]=new byte[1024];//将接受格式转化为byte数组
is.read(b1);//接收信息
String d=new String(b1);
String d1= "zw"; //接受验证码
int num=getStringCount(d, d1);//查看收到的信息中是否存在验证码
int wendu;int dianliang;
StringBuilder sbCode = new StringBuilder();
int begin=d.indexOf("zw");//将接收到的字符串自zw处以后的截取出来
int last=d.length();
String str3=d.substring(begin,last);
byte b2[]=str3.getBytes();
if(num!=0) {
wendu= b2[18]-0x40;
dianliang=b2[20];
sbCode.append(wendu);
sbCode.append(",");
sbCode.append(dianliang);
sbCode.append(",");
}//获得温度 电量的具体数据
String sb1=sbCode.toString();
socket.close();
return sb1;
}
/**
* 用于联通节点的重启和报警
* @param bytes
* @return
*/
public boolean getSocket1(String ip,String str) throws IOException{
//socket信号发送 字符转化16进制
//开启socket连接
Socket socket=new Socket(ip,8899);
for(int i=0;i<3;i++) {
//输出流
OutputStream os=socket.getOutputStream();
//将字符转化为字节
byte[] n=hexStrToBinaryStr(str);
//获取验证码
String str1=getCRC(n);
//将验证码拼接在字符串后边
String str2=str+str1;
//将完整的需要传输的字符串转化为字节数组
byte[] n1=hexStrToBinaryStr(str2);
//传输
// System.out.println("输出信息"+n1);
os.write(n1);
//创建接受信息
InputStream is=socket.getInputStream();
byte b1[]=new byte[1024];//将接受格式转化为byte数组
is.read(b1);//接收信息
String d=new String(b1);
String d1= "zw"; //接受验证码
int num=getStringCount(d, d1);//查看收到的信息中是否存在验证码
//System.out.println("接受信息num"+num);
if(num!=0) {
socket.close();
return true;
}
}
socket.close();
return false;
}
/**
* 计算验证码 将验证码拼接在需要发送的数据后边
* @param bytes
* @return
*/
public static String getCRC(byte[] bytes) {
int Reg_CRC=0xffff;
int Temp_reg=0x00;
int i,j;
for (i = 0; i < bytes.length; i++) {
Reg_CRC^= (int) bytes[i]++;
for (j = 0; j < 8; j++) {
if ((Reg_CRC & 0x0001) != 0) {
Reg_CRC=Reg_CRC>>1^0xA001;
}else {
Reg_CRC >>=1;
}
}
}
Temp_reg=Reg_CRC>>8;
int d=(Reg_CRC<<8|Temp_reg);
String b=Integer.toHexString(d);
String strh = b.substring(b.length() -4,b.length());
String strh1=strh.substring(strh.length() -2,strh.length());
String strh2= strh.substring(0,strh.length()-2);
String strh3=strh1+strh2;
return strh3;
}
/**
* 将十六进制字符转化为bety数组
*/
public static byte[] hexStrToBinaryStr(String hexString) {
hexString = hexString.replaceAll(" ", "");
int len = hexString.length();
int index = 0;
byte[] bytes = new byte[len / 2];
while (index < len) {
String sub = hexString.substring(index, index + 2);
bytes[index/2] = (byte)Integer.parseInt(sub,16);
index += 2;
}
return bytes;
}
/**
* 查看一段字符串在另一段字符串中的数量
* @param source
* @param src
* @return
*/
private static int getStringCount(String source, String src) {
int index = 0;
int count = 0;
int start = 0;
while ((index = source.indexOf(src, start)) != -1) {
count++;
start = index + 1;
}
return count;
}
}
这里包含了socket的通讯,十六进制的转化,字符串的截取,验证码的计算等,留作笔记以待下次使用