博客:http://blog.csdn.net/muyang_ren
项目环境与工具:Ubuntu14.04(64位)、S5pv210、PAD、context-M0、Android Studio、JSON、MySQL(服务器)、sqlite3(客户端)。
主要开发语言:C、Java
项目描述:手持设备接入服务器,服务器连接控制台,控制台通过ZigBee连接M0,通过这种数据连接手持设备和M0进行信息采集系统交互。控制台还提供摄像头的HTTP流媒体服务。
责任描述:
1、服务器实现客户端注册登录操作。
2、手持客户端(手机安卓端)接入服务器实时获取硬件状态数据,
3、手持客户端发送要改变的硬件信息给服务器,服务器接收到手机发送过来的要改变的硬件消息再转送给控制台。
4、利用JNI/HAL技术实现底层与APP的交互。
服务器
head.h
/*************************************************************************
> File Name: head.h
> Author: 梁惠涌
> Addr:
> Created Time: 2015年07月14日 星期五 18时13分16秒
************************************************************************/
#ifndef _HEAD_H
#define _HEAD_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
#include <mysql/mysql.h> //mysql
#include <signal.h>
#include <pthread.h>
#include </usr/local/include/json/json.h>
//server ip port
#define SER_PORT 8888
//#define SER_IP_ADDR "127.0.0.1"
#define SER_IP_ADDR "192.168.7.105"
//mysql
#define MYSQL_SERVER "localhost"
#define MYSQL_USER "root"
#define MYSQL_PASSWD "123456"
#define true 1
#define false 0
#define IS_json_val(buf,string) json_object_get_string(json_object_object_get(json_tokener_parse(buf),string))
extern void *phone_client(void *);
extern void *control_client(void *);
extern void start_mysql_init();
extern void server_socket_init(int *);
extern void sql_insert_user(const char *,const char*);
extern int sql_select_reg(const char *);
extern int sql_select_user(const char *,const char*);
extern void sql_insert_SHhardware(const char *,const char *,const char *,const char *,const char *,const char *,const char *,const char *,const char *);
extern char *get_time();
//extern void *send_to_control(void *);
extern void sql_insert_client_fd(int );
extern void sql_remove_client_fd(int );
extern void save_to_control_hardware(char *);
extern void send_hardware_all_client(char *);
extern void send_client_reg_OK(int);
extern void send_client_reg_false(int);
extern void send_client_login_OK(int);
extern void send_client_login_false(int);
MYSQL *my_con;
int control_fd;
int listen_fd, new_fd;
//控制台接入标志
volatile int control_flag;
//全局变量,控制台发送过来的最后一次硬件信息
struct json_object* control_hardware;
#endif
server.c
/*************************************************************************
> File Name: server.c
> Author: 梁惠涌
> Addr:
> Created Time: 2015年07月14日 星期三 21时09分09秒
************************************************************************/
#include "head.h"
int main(){
char read_buf[BUFSIZ];
pthread_t tid1, tid2;
//初始化控制台标志位
control_flag = false;
control_hardware = json_object_new_object();
control_hardware = NULL;
system("clear");
get_time();
printf( "Step 1:\n");
//数据库操作
start_mysql_init();
//服务器socket初始化
server_socket_init(&listen_fd);
/*(三)、与客户端通信 */
printf("-----------服务器启动!--------- \n");
while(1){
int ret;
new_fd = accept(listen_fd, NULL, NULL);
if(new_fd < 0){
perror("accept");
exit(-1);
}
bzero(read_buf,BUFSIZ);
ret = read(new_fd, read_buf, BUFSIZ-1);
if(ret >0 ){
printf("%s\n",read_buf);
//phone
if(strcmp(IS_json_val(read_buf,"flag"), "phone") == 0){
printf("the phone is Connect!\n");
pthread_create(&tid1, NULL, phone_client, (void *)&new_fd);
//control
}else if(strcmp(IS_json_val(read_buf,"flag"), "control") == 0){ //控制台语句
if(control_flag == true){
perror("error:控制台已接入一台!\n");
}else{
control_flag = true;
//printf("control_flag = %d\n",control_flag);
printf( "Step 2:\nthe control is Connect!\n");
printf("-----------控制台接入--------- \n");
//保存最后一次控制台的数据到control_hardware全局变量中
save_to_control_hardware(read_buf);
//存进数据库
sql_insert_SHhardware(IS_json_val(read_buf,"flag"),get_time(),"root",IS_json_val(read_buf,"tmp"),IS_json_val(read_buf,"damp"),IS_json_val(read_buf,"fan"),IS_json_val(read_buf,"buz"),IS_json_val(read_buf,"led"),IS_json_val(read_buf,"camare"));
pthread_create(&tid2, NULL, control_client, (void *)&new_fd);
}
}
}else{
continue;
}
}
close(listen_fd);
return 0;
}
thread.c
/*************************************************************************
> File Name: thread.c
> Author:
> Mail:
> Created Time: 2015年07月14日 星期五 10时33分51秒
************************************************************************/
#include "head.h"
void *control_client(void *arg){
pthread_detach(pthread_self());
int ret;
char control_buf[BUFSIZ];
control_fd = *(int *)arg;
while(1){
ret = read(control_fd, control_buf, BUFSIZ-1);
if(ret <=0){
printf("连接控制台失败,等待重连...\n");
break;
}else{
//让control_hardware始终存储最新的硬件信息
save_to_control_hardware(control_buf);
control_hardware = json_tokener_parse(control_buf);
sql_insert_SHhardware(IS_json_val(control_buf,"flag"),get_time(),
"root",IS_json_val(control_buf,"tmp"),
IS_json_val(control_buf,"damp"),
IS_json_val(control_buf,"fan"),
IS_json_val(control_buf,"buz"),
IS_json_val(control_buf,"led"),
IS_json_val(control_buf,"camare"));
//将硬件信息发送给所有的客户端
send_hardware_all_client(control_buf);
}
}
printf("Control Is Close!\n");
close(control_fd);
control_flag = false;
pthread_exit(0);
return NULL;
}
//
void *phone_client(void *arg){
pthread_detach(pthread_self());
int ret, client_fd, ok_login=false, ok_reg = false;
bool connected_flag = false;
char client_buf[BUFSIZ];
client_fd = *(int *)arg;
printf("Connect phone_client[%d]!\n",client_fd);
sql_insert_client_fd(client_fd);
//login and register
while((!ok_login)||(!ok_reg)){
bzero(client_buf,BUFSIZ);
ret = read(client_fd, client_buf, BUFSIZ-1);
if(ret <= 0 ){
printf("time :%s\n",get_time());
sql_remove_client_fd(client_fd);
close(client_fd);
pthread_exit(0);
return NULL;
}else{
printf("phone_client : %s\n",client_buf);
if( IS_json_val(client_buf,"type") == NULL){
connected_flag = true;
break;
}
if(strcmp(IS_json_val(client_buf,"type"), "login") == 0){
//对比数据库的用户表
if(sql_select_user(IS_json_val(client_buf,"username"),IS_json_val(client_buf,"password"))){
printf("==========================\n");
printf("phone_client[%d] : %s login!\n", client_fd, IS_json_val(client_buf,"username"));
printf("==========================\n");
ok_login = true;
send_client_login_OK(client_fd);
}else{
send_client_login_false(client_fd);
}
}else if(strcmp(IS_json_val(client_buf,"type"),"reg") == 0){
printf("phone_client[%d] - register : %s - %s\n",
client_fd,
IS_json_val(client_buf,"username"),
IS_json_val(client_buf,"password"));
//判断数据库内的有没有该用户名
if(sql_select_reg(IS_json_val(client_buf,"username")) == true){
printf("phone_client[%d] : 已存在该用户名:%s\n",client_fd, IS_json_val(client_buf,"username"));
send_client_reg_false(client_fd);
}else{
//注册用户
sql_insert_user(IS_json_val(client_buf,"username"),IS_json_val(client_buf,"password"));
send_client_reg_OK(client_fd);
}
}
}
}
//客户端连接后将数据库内最新的数据发送给客户端
const char *send_buf = json_object_to_json_string(control_hardware);
write(client_fd, send_buf, strlen(send_buf));
printf("Server -> send to client[%d] : %s\n",client_fd,send_buf);
while(1){
bzero(client_buf,BUFSIZ);
ret = read(client_fd, client_buf, BUFSIZ-1);
if(ret < 0){
printf("phone client[%d] : read client error!\n", client_fd);
break;
}
printf("phone_client[%d] : read from client : %s \n", client_fd, client_buf);
printf("phone_client[%d] Set[ %s : %s ]\n",client_fd,IS_json_val(client_buf,"set_type"),IS_json_val(client_buf,"set_val"));
if(control_flag == true){
write(control_fd, client_buf, strlen(client_buf));
}else{
printf("=== control is close! ===\n");
}
printf("phone_client[%d] : write to control:%s\n ",client_fd,client_buf);
}
printf("phone_client[%d] close!\n time :%s\n",client_fd, get_time());
sql_remove_client_fd(client_fd);
close(client_fd);
pthread_exit(0);
return NULL;
}
ulit.c
/*************************************************************************
> File Name: uilt.c
> Author:
> Mail:
> Created Time: 2015年07月14日 星期二 10时13分04秒
************************************************************************/
#include "head.h"
void start_mysql_init(){
//链接数据库
my_con = mysql_init(NULL);
if(!mysql_real_connect(my_con,MYSQL_SERVER,MYSQL_USER,MYSQL_PASSWD,NULL,0,NULL,0)){
fprintf(stderr, "%s\n", mysql_error(my_con));
exit(1);
}
printf("mysql Connect!\n");
printf("mysql version :%s\n",mysql_get_client_info());
//创建数据库文件 smart_home
if(mysql_query(my_con, "create database if not exists smart_home")) {
printf("Error %u: %s\n", mysql_errno(my_con), mysql_error(my_con));
exit(1);
}
//选取数据库文件 smart_home
if(mysql_query(my_con, "use smart_home")) {
printf("Error %u: %s\n", mysql_errno(my_con), mysql_error(my_con));
exit(1);
}
//创建数据库表 users
if(mysql_query(my_con, "create table if not exists users(username VARCHAR(20),password VARCHAR(20))")) {
printf("Error %u: %s\n", mysql_errno(my_con), mysql_error(my_con));
exit(1);
}
//创建数据库表 hardware
if(mysql_query(my_con, "create table if not exists SH_hardware(SH_flag VARCHAR(20),SH_time VARCHAR(40), SH_name VARCHAR(20), SH_tmp VARCHAR(20), SH_damp VARCHAR(20), SH_fan VARCHAR(20), SH_buz VARCHAR(20), SH_led VARCHAR(20),SH_camare VARCHAR(20))")) {
printf("Error %u: %s\n", mysql_errno(my_con), mysql_error(my_con));
exit(1);
}
//创建手机终端连接表 client_fd
if(mysql_query(my_con, "create table if not exists client_fd(client_fd int(8))")) {
printf("Error %u: %s\n", mysql_errno(my_con), mysql_error(my_con));
exit(1);
}
}
void server_socket_init(int *listen_fd){
/*(一)、socket初``始化*/
struct sockaddr_in sin;
//1、创建套接字
*listen_fd = socket(AF_INET,SOCK_STREAM, 0);
if(listen_fd < 0){
perror("socket error!\n");
exit(-1);
}
//2.1 填充
sin.sin_family = AF_INET, sin.sin_port = htons(SER_PORT);
sin.sin_addr.s_addr = inet_addr(SER_IP_ADDR);
bzero(sin.sin_zero, 8);
printf("server PORT:%d\n",SER_PORT);
printf("server IP :%s\n",SER_IP_ADDR);
//设置地址重用
int bReuseaddr=1;
if(setsockopt(*listen_fd,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(bReuseaddr)) != 0)
{
fprintf(stderr,"setsockopt IP error!\n");
exit(0);
}
//2.2 bing绑定
if(bind(*listen_fd, (struct sockaddr *)&sin,sizeof(sin))!=0){
perror("bind\n");
exit(-1);
}
//3、监听
listen(*listen_fd, 5);
}
void sql_insert_user(const char *username,const char *password){
char sql_insert[200];
sprintf(sql_insert, "INSERT INTO users(username,password) values(‘%s‘,‘%s‘);", username, password);
int res = mysql_query(my_con, sql_insert);
if (!res) {
printf("MySQL : Inserted %lu user\n", (unsigned long)mysql_affected_rows(my_con));
} else {
fprintf(stderr, "Insert error %d: %s func : %s\n", mysql_errno(my_con), mysql_error(my_con),__func__);
}
}
void sql_insert_client_fd(int client_fd){
char sql_insert[200];
sprintf(sql_insert, "INSERT INTO client_fd(client_fd) values(%d);",client_fd);
int res = mysql_query(my_con, sql_insert);
if(res){
fprintf(stderr, "Insert error %d: %s func: %s \n", mysql_errno(my_con), mysql_error(my_con),__func__);
}else{
printf("MySQL : INSERT client_fd[%d]\n",client_fd);
}
}
void sql_remove_client_fd(int client_fd){
char sql_insert[200];
sprintf(sql_insert, "DELETE from client_fd WHERE client_fd=%d",client_fd);
int res = mysql_query(my_con, sql_insert);
if (res) {
fprintf(stderr, "Delete error %d: %s\n", mysql_errno(my_con), mysql_error(my_con));
} else {
printf("MySQL : DELETE client_fd[%d]\n",client_fd);
}
}
int sql_select_user(const char *username,const char *password){
int res, i;
int iTableRow;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;
res = mysql_query(my_con, "select username,password from users"); //查询语句
if (res) {
printf("SELECT error:%s\n",mysql_error(my_con));
exit(0);
} else {
res_ptr = mysql_store_result(my_con); //取出结果集
if(res_ptr) {
iTableRow = mysql_num_rows(res_ptr);//行
//iTableCol = mysql_num_fields(res_ptr);//列
for(i=0; i<iTableRow; i++){
sqlrow = mysql_fetch_row(res_ptr);
if( (strcmp(username,sqlrow[0])==0 ) && (strcmp(password,sqlrow[1])==0)){
mysql_free_result(res_ptr);
return 1;
}
}
}
mysql_free_result(res_ptr);
}
return 0;
}
int sql_select_reg(const char *username){
int res, i;
int iTableRow;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;
res = mysql_query(my_con, "select username,password from users"); //查询语句
if (res) {
printf("SELECT error:%s\n",mysql_error(my_con));
exit(0);
} else {
res_ptr = mysql_store_result(my_con); //取出结果集
if(res_ptr) {
iTableRow = mysql_num_rows(res_ptr);//行
//iTableCol = mysql_num_fields(res_ptr);//列
for(i=0; i<iTableRow; i++){
sqlrow = mysql_fetch_row(res_ptr);
if(strcmp(username,sqlrow[0]) == 0){
mysql_free_result(res_ptr);
return 1;
}
}
}
mysql_free_result(res_ptr);
}
return 0;
}
// SH_hardware: SH_flag VARCHAR(20) SH_time VARCHAR(20) SH_name VARCHAR(20) SH_tmp VARCHAR(20)
// SH_damp VARCHAR(20) SH_fan VARCHAR(20) SH_buz VARCHAR(20) SH_led VARCHAR(20)
// SH_camare VARCHAR(20)
void sql_insert_SHhardware(const char *SH_flag,const char *SH_time,const char *SH_name,const char *SH_tmp,const char *SH_damp,const char *SH_fan,const char *SH_buz,const char *SH_led, const char *SH_camare){
char sql_insert[200];
sprintf(sql_insert, "INSERT INTO SH_hardware(SH_flag,SH_time,SH_name,SH_tmp,SH_damp,SH_fan,SH_buz,SH_led,SH_camare) values(‘%s‘,‘%s‘,‘%s‘,%s,‘%s‘,‘%s‘,‘%s‘,‘%s‘,‘%s‘);", SH_flag, SH_time,SH_name,SH_tmp,SH_damp,SH_fan,SH_buz,SH_led,SH_camare);
int res = mysql_query(my_con, sql_insert);
if (res) {
fprintf(stderr, "Insert error %d: %s\n", mysql_errno(my_con), mysql_error(my_con));
}
}
char *get_time(){
struct tm *p;
static char tmm[30];
time_t t;
time(&t);
p = localtime(&t);
sprintf(tmm,"%d:%d:%d-%d:%d:%d",1900+p->tm_year,1+p->tm_mon, p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
//strcpy(tmm, ctime(&t));
return tmm;
}
void save_to_control_hardware(char *control_buf){
control_hardware = json_tokener_parse(control_buf);
json_object_object_add(control_hardware, "flag", json_object_new_string("server"));
printf("%s\n", json_object_to_json_string(control_hardware));
}
void send_hardware_all_client(char *hardware_buf){
int res, i;
int iTableRow;
int client_fd;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;
res = mysql_query(my_con, "select client_fd from client_fd"); //查询语句
if (res) {
printf("SELECT error:%s\n",mysql_error(my_con));
exit(0);
} else {
res_ptr = mysql_store_result(my_con); //取出结果集
if(res_ptr) {
iTableRow = mysql_num_rows(res_ptr);//行
//iTableCol = mysql_num_fields(res_ptr);//列
for(i=0; i<iTableRow; i++){
sqlrow = mysql_fetch_row(res_ptr);
//取出客户端套接字
client_fd = atoi(sqlrow[0]);
write(client_fd, hardware_buf, strlen(hardware_buf));
printf("Control send client[%d]:%s\n",client_fd,hardware_buf);
}
}
}
mysql_free_result(res_ptr);
}
void send_client_reg_OK(int client_fd){
struct json_object *json_obj = json_object_new_object();
json_object_object_add(json_obj,"reg",json_object_new_string("ok"));
const char *send_buf = json_object_to_json_string(json_obj);
write(client_fd, send_buf, strlen(send_buf));
}
void send_client_reg_false(int client_fd){
struct json_object *json_obj = json_object_new_object();
json_object_object_add(json_obj,"reg",json_object_new_string("false"));
const char *send_buf = json_object_to_json_string(json_obj);
write(client_fd, send_buf, strlen(send_buf));
}
void send_client_login_OK(int client_fd){
struct json_object *json_obj = json_object_new_object();
json_object_object_add(json_obj,"login",json_object_new_string("ok"));
const char *send_buf = json_object_to_json_string(json_obj);
write(client_fd, send_buf, strlen(send_buf));
}
void send_client_login_false(int client_fd){
struct json_object *json_obj = json_object_new_object();
json_object_object_add(json_obj,"login",json_object_new_string("false"));
const char *send_buf = json_object_to_json_string(json_obj);
write(client_fd, send_buf, strlen(send_buf));
}
Makefile
#自动编译多个.c构成的项目,即把所有的.c编译成同一个可执行文件
CC:=gcc
CFLAGS:=-Wall -g -lpthread -ljson -lmysqlclient
SRC:=${wildcard *.c} #将当前目录下的以.c为后缀的文件名赋给SRC
OBJ:=${patsubst %.c,%.o,$(SRC)}#将Src中以.c为后缀的字符串替换成.o为后缀赋给OBJ
server:$(OBJ)
$(CC) -o [email protected] $^ $(CFLAGS)
%.o:%.c myhead.h
$(CC) -o [email protected] -c $< $(CFLAGS)
.PHONY:clean print
clean:
@rm -f *.o test .*.sw?
print:
@echo $(SRC)
@echo $(OBJ)
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-25 18:32:19