2015--智慧家庭(服务器)

博客: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: 20150714日 星期五 103351************************************************************************/

#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 $@ $^ $(CFLAGS)


%.o:%.c myhead.h
    $(CC) -o $@ -c $< $(CFLAGS) 

.PHONY:clean print
clean:
    @rm -f *.o test .*.sw?
print:
    @echo $(SRC)
    @echo $(OBJ)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值