1 准备工作
该程序主要接收下位机发来的离床上床消息,并存入数据库,达到实时监控床位状态的目的
1.1 开发环境
使用了java语言,平台是eclipse,JDK版本:1.7.0_13,数据库使用mysql,需要向程序中导入mysql-connector-java-5.1.28-bin.jar的驱动包
1.2 数据库建立
表名:RY
设计:
1.3 协议
发送在监测变化时
包头 | 床位 | 状态 | 保留 |
0xAAAA | 一个字节 | 一个字节 | 一个字节0XFF |
状态:
命令字 | 说明 |
0x01 | 上床 |
0x02 | 离床 |
2 代码简述
2.1 socket部分
serversocket.java 程序入口
public class ServerSocket {
public static void main(String[] args) {
new ServerListener().start(); //建立实时监听客服端
}
由于socket会阻塞进程,如果直接写在主线程中,程序就只能执行socket的功能,使用我另外开启一个线程,单独用来通信。
ServerListener.java
public class ServerListener extends Thread{
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(9999); //端口
while(true){
//每当有一个客服端连接就有一个socket
Socket socket = serverSocket.accept();//阻塞
System.out.println("有客服端链接-------");
ReceiveSocket cs = new ReceiveSocket(socket);//新线程
cs.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
这里每连接一个客服端,就想控制台输出一个消息,并又建立一个线程单独对其处理。
ReceiveSocket.java 消息接收与处理
public class ReceiveSocket extends Thread{
Socket socket;
int getCounter = 0; //定义接收到的数据大小
int bedNumber = 0; //床位
int state = 0 ; //状态
public ReceiveSocket(Socket s){
this.socket = s;
}
public void run()
{
try {
boolean connect = true; //连接成功了的
byte getData[] = new byte[5];
//包头(2)+床位(1)+状态(1)+保留(1) = 5个字节
InputStream isTemplet = null;
OutputStream osTemplet = null;
while(true)
{
try {
osTemplet = socket.getOutputStream();
isTemplet = socket.getInputStream();
} catch (Exception e) {
connect = false ;
System.out.println("Broken A");
break;
}
if(socket.isConnected()) //判断是否在连接中
{
try
{
getCounter=isTemplet.read(getData, 0, 5);
}
catch(IOException e)
{
e.printStackTrace();
System.out.println("Broken B");
connect = false;
break;
}
}
//存入数据库
//System.out.println(getCounter); //打印出接收到的数据个数
if(getData[0] == -86 && getData[1] == -86) //0xaa就是-86
{
bedNumber =getData[2];//得到床位数
state = getData[3];//得到状态值
System.out.println(bedNumber);
System.out.println(state);
DB_Connection a =new DB_Connection(bedNumber,state);
getData[0] == 0; //防止多次进入
}
}
} catch (Exception e) {
e.printStackTrace();//在命令行打印异常信息在程序中出错的位置及原因
}
}
}
这里循环监听,按照协议每次取出5个字节数据,解析后存入数据库
2.2 数据库部分
DB_Connection.java 数据库操作
public class DB_Connection {
String Connection="jdbc:mysql://localhost:3306/RY?"+
"user=root&password=&characterEncoding=UTF8";
String uri = "jdbc:mysql://localhost:3306/RY?";
String user = "user=root&password=&characterEncoding=UTF8";
String connet = "jdbc:mysql://xxx.xxx.xxx.xxx:3306/RY?"
+ "user=root&password=&useUnicode=true&characterEncoding=UTF8";
String inSql = null;
public DB_Connection(int bedNumber,int state)
{
java.sql.Connection conn = null;
java.sql.Statement stmt =null;
//注册驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("Broken driver");
e.printStackTrace();
}
//创建连接
try {
conn = DriverManager.getConnection(connet);
//获取表达式
stmt= conn.createStatement();
} catch (SQLException e) {
System.out.println("Broken conn");
e.printStackTrace();
}
Date date = new Date();//获得系统时间.
String nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);//将时间格式转换成符合Timestamp要求的格式.
Timestamp goodsC_date = Timestamp.valueOf(nowTime);//把时间转换
if(state ==1)
inSql = "insert into message(bed_Number,state,Dtime) values('" + bedNumber + "','back','" + goodsC_date + "')";
else {
inSql = "insert into message(bed_Number,state,Dtime) values('" + bedNumber + "','leave','" + goodsC_date + "')";
}
try {
stmt.executeUpdate(inSql);
} catch (SQLException e) {
System.out.println("Broken insert");
e.printStackTrace();
}
try {
stmt.close();
conn.close();
} catch (SQLException e) {
System.out.println("Broken close");
e.printStackTrace();
}
}
}
一开始的字符串是用来定义连接数据库的,那些xxx就是ip地址,3306就是默认数据库的端口,RY就是表明
我这里的构造函数是直接传入了两个需要得到的消息,并简单判断一下,按照格式存入数据库。
3 测试
3.1 测试多客服端连接情况
测试方法:开启两个网络调试助手,运行服务器端程序。使用网络调试助手连接服务器,查看情况,
3.2 测试信息录入情况
测试方法:在上面基础上。在分别按照协议发送状态信息,查看数据库是否记录。
4 下载
提供的代码估计和上文的不同,下面链接是上学的时候为学长代做的毕设的全套代码,是一个实际应用,可以点击视频连接看到演示和讲解。
嵌入式软件|windows客户端|服务器源码
GITHUB 上了班之后估计很难会用到GITHUB咯
5 讲解视频