这个程序是源于我的一个智能家居项目,需要将传感器(sensor)接收过来的数据,通过ZigBee模块发送到客户端,并在客户端的web页面展示。
- 服务端线程,用于模拟数据,封装成xml格式,通过socket通信发送给客户端
package com.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.StringReader;
import java.net.ServerSocket;
import java.net.Socket;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import com.client.Sensor;
public class ServerThread implements Runnable {
private final static int PORT = 3831;// 端口号
private static ServerSocket serverSocket;
private static Socket socket = null;
private BufferedReader bufferedReader = null;
private PrintStream print = null;
Sensor sensor = new Sensor();
public ServerThread() throws IOException {
// TODO Auto-generated constructor stub
serverSocket = new ServerSocket(PORT);
socket = serverSocket.accept();//阻塞等待
bufferedReader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
}
public static void main(String[] args) throws IOException {
new Thread(new ServerThread()).start();
}
/**
* 解析xml成javabean对象,并填充javabean属性
* @param xml
* @param obj
* @return
*/
@SuppressWarnings("unchecked")
public static <Javebean> Javebean parseXML(String xml, Class<Javebean> obj) {
Javebean javebean = null;
try {
//获得JAXBContext实例,用于实现xml和java树之间的互转
JAXBContext jaxbContext = JAXBContext.newInstance(obj);
//创建解组器对象
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
//将字符串格式的xml解析成对象,并填充相应的属性
javebean = (Javebean) unmarshaller.unmarshal(new StringReader(xml));
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return javebean;
}
@Override
public void run() {
// TODO Auto-generated method stub
String receivedXML = null;//用于接收xml,每次接收完会清空
synchronized (this) {
try {
while(true)
{
//读取发送过来的xml
receivedXML = bufferedReader.readLine();
//将获取的xml解析成sensor类,并填充属性
Sensor sensor = parseXML(receivedXML,Sensor.class);
//获得数据
System.out.println(sensor.getSensor_id()+" "+sensor.getCurrent_concentrations()+" "+sensor.getThreshold());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
- 客服端线程,用于接收来自客户端的xml格式数据,并解析成javabean,通过操作javabean对象来获取数据
package com.client;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;
public class ClientThread implements Runnable{
private final String URL = "127.0.0.1";//ip地址
private final int PORT = 3831;//端口号
private Socket socket = null;
private PrintWriter printWriter = null;
Sensor sensor = new Sensor();
public ClientThread() throws IOException
{
socket = new Socket(URL,PORT);
printWriter = new PrintWriter(socket.getOutputStream(),true);
}
/**
* 主入口函数
* @param args
*/
public static void main(String[] args) {
try {
//启动线程
new Thread(new ClientThread()).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//封装成xml
public static String getXML(Object obj,String encoding)
{
String getedXML = "";
try {
//获得JAXBContext实例,用于实现xml和java树之间的互转
JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass());
//创建编组器对象
Marshaller marshaller = jaxbContext.createMarshaller();
//设置转成xml自动格式化
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//设置编码
marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
StringWriter stringWriter = new StringWriter();
//将obj转成xml,并写入一个字符流
marshaller.marshal(obj, stringWriter);
getedXML = stringWriter.toString();
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return getedXML;
}
/**
* 获取min,到max范围的随机整数
* @param min
* @param max
* @return
*/
public static int getInt(int min,int max)
{
Random random = new Random();
int getedInt = random.nextInt(max)%(max-min+1) + min;
return getedInt;
}
/**
* 获取min,到max范围的随机浮点数
* @param min
* @param max
* @return
*/
public static float getFloat(float min,float max)
{
Random random = new Random();
float getedFloat = random.nextFloat()*(max-min) + min;
return getedFloat;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
synchronized (this) {
try {
Thread.sleep(3000);//3000毫秒发一次
//填充数据
sensor.setSensor_id(getInt(1,2));
sensor.setCurrent_concentrations(getFloat(10f,50f));
sensor.setThreshold(30.5f);
//取出换行符
String sendedXML = getXML(sensor,"utf-8");
Pattern p = Pattern.compile("\n");
Matcher m = p.matcher(sendedXML);
sendedXML = m.replaceAll(" ");
//发送xml到服务器
printWriter.println(sendedXML);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
- javabean类,用于填充数据
package com.client;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "sensor")//不可少,标识根元素
@XmlType(propOrder = { "sensor_id", "current_concentrations", "threshold"})
public class Sensor implements Serializable{
@XmlElement(required = true)
private int sensor_id;//传感器id
@XmlElement(required = true)
private float current_concentrations;//当前浓度
@XmlElement(required = true)
private float threshold;//正常浓度
public int getSensor_id() {
return sensor_id;
}
public void setSensor_id(int sensor_id) {
this.sensor_id = sensor_id;
}
public float getCurrent_concentrations() {
return current_concentrations;
}
public void setCurrent_concentrations(float current_concentrations) {
this.current_concentrations = current_concentrations;
}
public float getThreshold() {
return threshold;
}
public void setThreshold(float threshold) {
this.threshold = threshold;
}
@Override
public String toString() {
return "Sensor [sensor_id=" + sensor_id + ", current_concentrations="
+ current_concentrations + ", threshold=" + threshold + "]";
}
}
- 4.