赞
踩
该项目由客户端和服务器两端程序组成,以树莓派为客户端,远程服务器为服务器端,利用socket通信,将树莓派上采集的ds18b20的温度传感数据发送到服务器端。如果断开连接,客户端将采集的数据存于sqlite3数据库中,同样服务器端也会把每次接收到的数据存于sqlite3数据库中。
1.树莓派上运行socket客户端程序, 每隔30秒以字符串“设备号/日期时间/温度”形式上报采样温度,设备号便于服务器端区分是哪个树莓派客户端,如“RPI200/2022.4.4-12:01/28.00”;
2.通过命令行参数指定服务器端IP地址和端口以及间隔采样时间;
3.程序放到后台运行,并通过syslog记录程序的运行出错、调试日志;
4.程序可以捕捉kill信号正常退出;
5.当服务器断开时,将采集的数据存放至本地数据库中,等再次连接上服务器时,将已保存在数据库中的数据重新发送给服务器。
客户端程序流程图如下:
1.服务器程序运行啊在Linux服务器上;
2.通过命令行指定监听的端口;
3.程序能够捕捉kill信号正常退出;
4.服务器支持多个客户端并发访问,选择epoll实现多路复用;
5.服务器收到每个客户端的数据都解析后保存到数据库中,接收到的格式为:“设备号/日期时间/温度”,如“RPI200/2022.4.4-12:01/28.00”;
服务器端程序流程图如下:
客户端代码:
/********************************************************************************* * Copyright: (C) 2022 Zhang Changxing<ZhangChangxingVIP@163.com> * All rights reserved. * * Filename: client.c * Description: This file Collect the temperature data on the ds18b20 sensor and send it to the server. If the sending fails, it will be stored in the database temperature.db. * * Version: 1.0.0(04/04/2022) * Author: Zhang Changxing <ZhangChangxingVIP@163.com> * ChangeLog: 1, Release initial version on "04/04/2022 05:44:50 AM" * ********************************************************************************/ #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <sys/time.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <string.h> #include <getopt.h> #include <time.h> #include <sqlite3.h> #include <signal.h> #include <syslog.h> #include <libgen.h> #include <linux/tcp.h> #include <netinet/in.h> #include <netinet/ip.h> #define TABLE_NAME "RPI1" struct timeval tv; struct tm* st; char datime[100]; static double current_time = 0; static double last_time = 0; char *buftok[3]; struct sockaddr_in servaddr; int sockfd = -1; int port =0; char *ip_addr = NULL; int connfd = -1; static int count = 0; int rc = -1; sqlite3 *db; char *zErrMsg = 0; int iTableExist = 0; char write_buffer2[100]; int g_sigstop = 0; struct tcp_info info; int temperature (float *temp); static inline void print_usage(char *programe); void sqlite_init(void); static int callback(void *NotUsed, int argc, char **argv, char **azColName); void sqlite_create_table(char *table_name); void sqlite_inset(char *buftok[], char *table_name); int sqlite_delete(int id, char *table_name); double getime(char *datime); int client_socket_init(void); int sendata(int sockfd, char *buftok[]); int sqlite_table_exist(char *table_name); static int table_exist_callback(void *data, int argc, char **argv, char **azColName); int table_row_count(char *table_name); static int callback_row_count(void *NotUsed, int argc, char **argv, char **azColName); int sendata2(int sockfd, char *table_name, int count); static int sendata2_callback(void *data, int argc, char **argv, char **azColName); void signal_stop(int signum); int SocketConnected(int sockfd); int main (int argc, char **argv) { float temp = 0; int rv = -1; int ch; int daemon_run =0; int con_status = 1; char count_buffer[20]; struct sigaction sigact; struct sigaction sigign; char *programe_name; char temp_buffer[10]; struct option opts[] = { {"ip_addr", required_argument, NULL, 'i'}, {"port", required_argument, NULL, 'p'}, {"daemon", no_argument, NULL, 'b'}, {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0} }; while((ch = getopt_long(argc, argv, "i:p:bh", opts, NULL)) != -1) { switch(ch) { case 'i': { ip_addr = optarg; break; } case 'p': { port = atoi(optarg); break; } case 'b': { daemon_run = 1; break; } case 'h': { print_usage(argv[0]); break; } default: { printf("Invalid argument\n"); return -1; } } } if(port == 0 || ip_addr == NULL) { printf("Invalid port or IP address is NULL!\n"); return -2; } if(daemon_run) { if(daemon(0, 0)) { printf("Running daemon failure:%s\n", strerror(errno)); } printf("Running daemon successfully!\n"); } programe_name = basename(argv[0]); openlog(programe_name, LOG_CONS|LOG_PID, 0); sigemptyset(&sigign.sa_mask); sigign.sa_flags = 0; sigign.sa_handler = SIG_IGN; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigact.sa_handler = signal_stop; //sigaction(SIGINT, &sigign, 0); sigaction(SIGUSR1, &sigact, 0); sigaction(SIGUSR2, &sigact, 0); connfd = client_socket_init(); if(connfd < 0) { printf("Client connect server failure:%s\n", strerror(errno)); con_status =0; } sqlite_init(); if(sqlite_table_exist(TABLE_NAME) == 0) { sqlite_create_table(TABLE_NAME); } //sqlite_delete(0, TABLE_NAME); count = table_row_count(TABLE_NAME); gettimeofday(&tv, NULL); current_time = tv.tv_sec; while(!g_sigstop) { gettimeofday(&tv, NULL); last_time = tv.tv_sec; sleep(2); printf("\n\n\n"); if(SocketConnected(sockfd) == 0) { con_status = 0; } if((last_time - current_time) >= 30) { if((rv = temperature(&temp))< 0) { printf("Execute temperature failure!\n"); return -3; } last_time = getime(datime); current_time = last_time; memset(count_buffer, 0, sizeof(count_buffer)); sprintf(count_buffer, "%d", (count+1)); memset(temp_buffer, 0, sizeof(temp_buffer)); sprintf(temp_buffer, "%f", temp); buftok[0] = count_buffer; buftok[1] = "RPI1"; buftok[2] = datime; buftok[3] = temp_buffer; if(con_status) { if(sendata(sockfd, buftok) < 0) { sqlite_inset(buftok, TABLE_NAME); count++; con_status = 0; close(sockfd); } } else { //connfd = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); connfd = client_socket_init(); if(connfd < 0) { printf("Client connect server failure:%s\n", strerror(errno)); con_status =0; sqlite_inset(buftok, TABLE_NAME); count++; close(sockfd); } else { con_status =1; if(sendata(sockfd, buftok) < 0) { sqlite_inset(buftok, TABLE_NAME); count++; close(sockfd); } } } } else if(count >0) { if(con_status) { if(sendata2(sockfd,TABLE_NAME, count) < 0) { con_status = 0; close(sockfd); } else { if(sqlite_delete(count, TABLE_NAME) == 0) { count--; } } } else { //connfd = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); connfd = client_socket_init(); if(connfd < 0) { printf("Client connect server failure:%s\n", strerror(errno)); con_status = 0; close(sockfd); } else { con_status = 1; if(sendata2(sockfd, TABLE_NAME, count) < 0) { con_status = 0; close(sockfd); } else { if(sqlite_delete(count, TABLE_NAME) == 0) { count--; } } } } } } return 0; } static int sendata2_callback(void *data, int argc, char **argv, char **azColName) { memset(write_buffer2, 0, sizeof(write_buffer2)); sprintf(write_buffer2, "%s/%s/%s", argv[1], argv[2], argv[3]); printf("write_buffer2:%s\n", write_buffer2); return 0; } int sendata2(int sockfd, char *table_name, int count) { int write_rv2 = -1; char sendata_buffer2[100]; memset(sendata_buffer2, 0, sizeof(sendata_buffer2)); sprintf(sendata_buffer2, "select * from %s limit 1 offset %d", table_name, (count-1)); rc = sqlite3_exec(db, sendata_buffer2, sendata2_callback, 0, &zErrMsg); write_rv2 = write(sockfd, write_buffer2, strlen(write_buffer2)); if(write_rv2 < 0) { printf("Send data to sever failure:%s\n", strerror(errno)); return -1; } syslog(LOG_NOTICE, "Send data to sever successfully!\n"); return 0; } int sendata(int sockfd, char *buftok[]) { int write_rv1 = -1; char sendata_buffer1[100]; memset(sendata_buffer1, 0, sizeof(sendata_buffer1)); sprintf(sendata_buffer1, "%s/%s/%s", buftok[1], buftok[2], buftok[3]); printf("sendata sendata_buffer1:%s\n", sendata_buffer1); write_rv1 = write(sockfd, sendata_buffer1, strlen(sendata_buffer1)); if(write_rv1 < 0) { printf("Send data to sever failure:%s\n", strerror(errno)); return -1; } printf("Send data to sever successfully!\n"); return 0; } int sqlite_table_exist(char *table_name) { char table_exist[512]; sprintf(table_exist, "SELECT COUNT(*) FROM sqlite_master where type ='table' and name ='%s';", table_name); rc = sqlite3_exec(db, table_exist, table_exist_callback, 0, &zErrMsg); if(rc != SQLITE_OK) { printf("sqlite_table_exist:%s\n", zErrMsg); sqlite3_free(zErrMsg); exit(0); } if(iTableExist) { syslog(LOG_NOTICE, "%s is exist!\n", table_name); return iTableExist; } else { return iTableExist; } } static int table_exist_callback(void *data, int argc, char **argv, char **azColName) { if ( 1 == argc) { iTableExist = atoi(*(argv)); } return 0; } int client_socket_init(void) { sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0) { printf("Create socket failure:%s\n", strerror(errno)); } memset(&servaddr, 0 ,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); servaddr.sin_addr.s_addr = inet_addr(ip_addr); //printf("port:%d, ip_addr:%s, sockfd:%d\n", port, ip_addr, sockfd); connfd = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); return connfd; } double getime(char *datime) { gettimeofday(&tv, NULL); last_time = tv.tv_sec; st = localtime(&tv.tv_sec); memset(datime, 0, sizeof(datime)); sprintf(datime, "%05d:%02d:%02d--%02d:%02d:%02d", st->tm_year, st->tm_mon, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec); return last_time; } static int callback_row_count(void *NotUsed, int argc, char **argv, char **azColName) { count = atoi(argv[0]); return 0; } int table_row_count(char *table_name) { char row_count[100]; sprintf(row_count, "SELECT COUNT(*) from %s", table_name); rc = sqlite3_exec(db, row_count, callback_row_count, 0, &zErrMsg); if( rc != SQLITE_OK ) { printf("table_row_count: %s\n", zErrMsg); sqlite3_free(zErrMsg); } else { return count; } } int sqlite_delete(int id, char *table_name) { char sql_delete[100]; sprintf(sql_delete, "DELETE from %s where ID=%d;SELECT * from %s;", table_name, count, table_name); //sql = "DELETE from COMPANY where ID=2; " \ // "SELECT * from COMPANY"; rc = sqlite3_exec(db, sql_delete, 0, 0, &zErrMsg); if( rc != SQLITE_OK ) { fprintf(stderr, "Sqlite_delete error: %s\n", zErrMsg); sqlite3_free(zErrMsg); return -1; } else { return 0; } } void sqlite_inset(char *buftok[], char *table_name) { char sql_buffer[512]; char *ID1 = buftok[0]; char *SN1 = buftok[1]; char *DATIME1 = buftok[2]; char *TEMPERATURE1 = buftok[3]; printf("Inset data to TABLE %s: ", TABLE_NAME); printf("ID1:%s ", buftok[0]); printf("SN1:%s ", buftok[1]); printf("DATIME1:%s ", buftok[2]); printf("TEMPERATURE1:%s \n ", buftok[3]); #if 0 syslog(LOG_NOTICE, "Inset data to TABLE %s: ", TABLE_NAME); syslog(LOG_NOTICE, "ID1:%s ", buftok[0]); syslog(LOG_NOTICE, "SN1:%s ", buftok[1]); syslog(LOG_NOTICE, "DATIME1:%s ", buftok[2]); syslog(LOG_NOTICE, "TEMPERATURE1:%s \n ", buftok[3]); #endif sprintf(sql_buffer, "INSERT INTO %s VALUES ('%s', '%s', '%s', '%s');" ,table_name, ID1, SN1, DATIME1, TEMPERATURE1); rc = sqlite3_exec(db, sql_buffer, callback, 0, &zErrMsg); if( rc != SQLITE_OK ) { printf("Sqlite_inset: %s\n", zErrMsg); sqlite3_free(zErrMsg); } else { syslog(LOG_NOTICE, "Last data inset table successfully\n"); } return; } void sqlite_create_table(char *table_name) { char create_table[100]; sprintf(create_table, "CREATE TABLE %s(ID INT PRIMARY KEY, SN CHAR(10),DATIME CHAR(50),TEMPERATURE CHAR(10));", table_name); rc = sqlite3_exec(db, create_table, callback, 0, &zErrMsg); if(rc != SQLITE_OK) { printf("Sqlite_create_table:%s\n", zErrMsg); sqlite3_free(zErrMsg); exit(0); } else { syslog(LOG_NOTICE, "Table created successfully!\n"); } return; } static int callback(void *NotUsed, int argc, char **argv, char **azColName) { int i; for(i=0; i<argc; i++) { printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } void sqlite_init(void) { rc = sqlite3_open("temperature.db", &db); if(rc) { printf("Can't open database:%s\n", sqlite3_errmsg(db)); exit(0); } else { syslog(LOG_NOTICE, "Opened database successfully\n"); } } static inline void print_usage(char *programe) { printf("Usage:%s[OPTION]....\n", programe); printf("-p[port]:Socket sever port address\n"); printf("-b[daemon]:Start daemon!\n"); printf("-h[help]:Display this help information\n"); printf("\nExample:%s -b -p 6667\n", programe); return; } void signal_stop(int signum) { if(SIGUSR1 == signum) { printf("signum SIGUSR1 detected!\n"); } else if(SIGUSR2 == signum) { printf("signum SIGUSR2 detected!\n"); } g_sigstop = 1; } int SocketConnected(int sockfd) { if (sockfd <= 0) return 0; //struct tcp_info info; int len = sizeof(info); getsockopt(sockfd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) & len); if ((info.tcpi_state == 1)) { printf("socket connected\n"); return 1; } else { printf("socket disconnected\n"); return 0; } } int temperature (float *temp) { DIR *dir = NULL; struct dirent *drt = NULL; char *string = NULL; int fd = -1; char buf[512]; char *str; char directory[100] = "/sys/bus/w1/devices/"; if((dir = opendir(directory)) == NULL) { printf("open directory %s failure:%s\n", directory, strerror(errno)); return -1; } while((drt = readdir(dir)) != NULL) { if(strstr(drt->d_name, "28-") != NULL) { string = drt->d_name; break; } } if(string == NULL) { printf("read directory name failure:%s\n", strerror(errno)); return -2; } string = strcat(directory, string); string = strcat(directory, "/w1_slave"); fd = open(string, O_RDONLY); if(fd < 0) { printf("open %s\n failure:%s\n", string, strerror(errno)); return -3; } memset(buf, 0, sizeof(buf)); if(read(fd, buf, sizeof(buf)) < 0) { printf("read data from w1_slave failure:%s\n", strerror(errno)); close(fd); return -4; } if((str = strstr(buf, "t=")) == NULL) { printf("temperature not found:%s\n", strerror(errno)); close(fd); return -5; } str = str +2; *temp = atof(str)/1000; syslog(LOG_NOTICE, "the temperature is %f\n", *temp); close(fd); return 0; }
/********************************************************************************* * Copyright: (C) 2022 Zhang Changxing<ZhangChangxingVIP@163.com> * All rights reserved. * * Filename: server.c * Description: This file used to receive data sent by the device,and stored in the database. * * Version: 1.0.0(4/2/2022) * Author: Zhang Changxing <ZhangChangxingVIP@163.com> * ChangeLog: 1, Release initial version on "04/2/2022 15:45:31 PM" * ********************************************************************************/ #include <stdio.h> #include <arpa/inet.h> #include <ctype.h> #include <unistd.h> #include <getopt.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <sys/epoll.h> #include <sys/time.h> #include <sys/resource.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sqlite3.h> #include <syslog.h> #include <libgen.h> #define MAX_EVENTS 512 #define TABLE_NAME "COMPANY29" sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; static int k = 0; int *ptr = NULL; int iTableExist = 0; int connfd = -1; static inline void print_usage(char *programe); int socket_server_init(char *listen_ip, int port); void set_socket_rimit(void); static int callback(void *NotUsed, int argc, char **argv, char **azColName); void sqlite_init(void); void sqlite_create_table(char *table_name); void sqlite_inset(char *buftok[], char *table_name); int sqlite_table_exist(char *table_name); static int table_exist_callback(void *data, int argc, char **argv, char **azColName); int main (int argc, char **argv) { struct epoll_event event; struct epoll_event event_array[MAX_EVENTS]; int listenfd; char buf[1024]; int ch; int port = 0; int epollfd = -1; int events = -1; int daemon_run = 0; int i; int rev; char *buftok[3]; int j; char *p = NULL; char *programe_name; programe_name = basename(argv[0]); struct option opts[] = { {"port", required_argument, NULL, 'p'}, {"help", no_argument, NULL, 'b'}, {0, 0, 0, 0} }; while((ch = getopt_long(argc, argv, "p:h", opts, NULL)) != -1) { switch(ch) { case 'b': { daemon_run = 1; break; } case 'p': { port = atoi(optarg); break; } case 'h': { print_usage(argv[0]); break; } default: { printf("Invalid argument!\n"); return -1; } } } if(!port) { printf("The port is NULL!\n"); return -2; } if(daemon_run) { if(daemon(0, 0) < 0) { printf("Runing daemon failure:%s\n", strerror(errno)); return -3; } printf("Runing daemon successfully!\n"); } openlog(programe_name, LOG_CONS|LOG_PID, 0); set_socket_rimit(); listenfd = socket_server_init(NULL, port); epollfd = epoll_create(MAX_EVENTS); if(epollfd < 0 ) { syslog(LOG_EMERG, "Create epoll failure:%s\n", strerror(errno)); return -4; } event.events = EPOLLIN; event.data.fd = listenfd; if((epoll_ctl(epollfd, EPOLL_CTL_ADD,listenfd, &event)) < 0) { syslog(LOG_EMERG, "Execute epoll_ctl failure:%s\n", strerror(errno)); return -5; } sqlite_init(); // if(sqlite_table_exist(TABLE_NAME) == 0) // { // sqlite_create_table(TABLE_NAME); // } while(1) { sleep(2); events = epoll_wait(epollfd, event_array, MAX_EVENTS, -1); for(i = 0; i < events--; i++) { if(event_array[i].events == EPOLLERR || event_array[i].events == EPOLLHUP) { syslog(LOG_WARNING, "Epoll wait eorr or hup!\n"); epoll_ctl(epollfd, EPOLL_CTL_DEL, event_array[i].data.fd,NULL); close(event_array[i].data.fd); } if(event_array[i].data.fd == listenfd) { connfd = accept(listenfd, NULL, NULL); if(connfd < 0) { syslog(LOG_WARNING, "Server connect new client failure:%s\n", strerror(errno)); close(connfd); continue; } printf("Server connect new client[%d] successfully!\n", connfd); event.events = EPOLLIN; event.data.fd = connfd; if((epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &event)) < 0) { syslog(LOG_WARNING, "Add connfd to epollfd list failure:%s\n", strerror(errno)); close(event_array[i].data.fd); continue; } } else { memset(buf, 0, sizeof(buf)); rev = read(connfd, buf, sizeof(buf)); if(rev < 0) { syslog(LOG_WARNING, "Read data from client[%d] failure:%s\n", connfd, strerror(errno)); if(epoll_ctl(epollfd, EPOLL_CTL_DEL, event_array[i].data.fd, NULL) < 0 ) { syslog(LOG_WARNING, "Delete connfd to epollfd list failure:%s\n", strerror(errno)); } close(event_array[i].data.fd); continue; } else if(rev == 0) { syslog(LOG_WARNING, "Client[%d] disconnect!\n", connfd); continue; } p = strtok(buf, "/"); while(p) { buftok[j] = p; ++j; p = strtok(NULL, "/"); } if(sqlite_table_exist(buftok[0]) > 0) { sqlite_inset(buftok, buftok[0]); } else { sqlite_create_table(buftok[0]); sqlite_inset(buftok, buftok[0]); } } } } return 0; } void sqlite_inset(char *buftok[], char *table_name) { char sql_buffer[512]; char *SN1 = buftok[0]; char *DATIME1 = buftok[1]; char *TEMPERATURE1 = buftok[2]; printf("Accept client[%d] data successfully!\n", connfd); printf("SN1:%s\n", buftok[0]); printf("DATIME1:%s\n", buftok[1]); printf("TEMPERATURE1:%s\n", buftok[2]); sprintf(sql_buffer, "INSERT INTO %s VALUES ('%s', '%s', '%s');" ,table_name, SN1, DATIME1, TEMPERATURE1); rc = sqlite3_exec(db, sql_buffer, callback, 0, &zErrMsg); if( rc != SQLITE_OK ) { syslog(LOG_WARNING, "sqlite_inset: %s\n", zErrMsg); sqlite3_free(zErrMsg); } else { fprintf(stdout, "Records created successfully\n"); } return; } int sqlite_table_exist(char *table_name) { char table_exist[512]; sprintf(table_exist, "SELECT COUNT(*) FROM sqlite_master where type ='table' and name ='%s';", table_name); rc = sqlite3_exec(db, table_exist, table_exist_callback, 0, &zErrMsg); if(rc != SQLITE_OK) { syslog(LOG_WARNING, "sqlite_table_exist:%s\n", zErrMsg); sqlite3_free(zErrMsg); exit(0); } if(iTableExist) { syslog(LOG_NOTICE, "%s is exist!\n", table_name); return iTableExist; } else { return iTableExist; } } static int table_exist_callback(void *data, int argc, char **argv, char **azColName) { if ( 1 == argc) { iTableExist = atoi(*(argv)); } return 0; } void sqlite_create_table(char *table_name) { char create_table[100]; sprintf(create_table, "CREATE TABLE %s(SN CHAR(10),DATIME CHAR(50),TEMPERATURE CHAR(10));", table_name); rc = sqlite3_exec(db, create_table, callback, 0, &zErrMsg); if(rc != SQLITE_OK) { syslog(LOG_WARNING, "sqlite_create_table:%s\n", zErrMsg); sqlite3_free(zErrMsg); exit(0); } else { printf("Table created successfully!\n"); } return; } static int callback(void *NotUsed, int argc, char **argv, char **azColName) { int i; for(i=0; i<argc; i++) { printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } void sqlite_init(void) { rc = sqlite3_open("temperature.db", &db); if(rc) { syslog(LOG_NOTICE, "Can't open database:%s\n", sqlite3_errmsg(db)); exit(0); } else { fprintf(stderr, "Opened database successfully\n"); } } static inline void print_usage(char *programe) { printf("Usage:%s[OPTION]....\n", programe); printf("-p[port]:Socket sever port address\n"); printf("-b[daemon]:Runing programe in background!\n"); printf("-h[help]:Display this help information\n"); printf("\nExample:%s -b -p 6667\n", programe); return; } int socket_server_init(char *listen_ip, int port) { struct sockaddr_in servaddr; int rv = -1; int on = 1; int listenfd = -1; listenfd = socket(AF_INET, SOCK_STREAM, 0); if(listenfd < 0) { syslog(LOG_EMERG, "Create socket failure:%s\n", strerror(errno)); rv = -1; goto CleanUp; } setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on , sizeof(on)); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); if(listen_ip == NULL) { servaddr.sin_addr.s_addr = htonl(INADDR_ANY); } else { if(inet_pton(AF_INET, listen_ip, &servaddr.sin_addr) < 0) { syslog(LOG_EMERG, "Execute inet_pton failure:%s\n", strerror(errno)); rv = -2; goto CleanUp; } } if((bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) < 0) { syslog(LOG_EMERG, "Bind the IP and port failure:%s\n", strerror(errno)); rv = -3; goto CleanUp; } listen(listenfd, 50); rv = listenfd; goto CleanUp; CleanUp: if(rv > 0) return listenfd; else return rv; } void set_socket_rimit(void) { struct rlimit limit; getrlimit(RLIMIT_NOFILE, &limit); limit.rlim_cur = limit.rlim_max; setrlimit(RLIMIT_NOFILE, &limit); return; }
1.客户端和服务器端安装数据库
sqlite3下载网址:http://www.sqlite.org/download.html
$ tar xvzf sqlite-autoconf-3071502.tar.gz
$ cd sqlite-autoconf-3071502
$ ./configure --prefix=/usr/local
$ make
$ make install
2.在树莓派上安装客户端
$ wget https://gitee.com/moqain/socket_ds18b20/tree/master/socket_client
3.在服务器上安装服务器端
$ wget https://gitee.com/moqain/socket_ds18b20/tree/master/socket_server
1.编译运行服务器端
$ gcc server.c -o server -lsqlite3
$ ./server -p 端口号
2.编译运行客户端
$ gcc client.c -o client -lsqlite3
$ ./client -p 端口号 -i IP地址
https://gitee.com/moqain/socket_ds18b20/tree/master
整个项目需要用到的知识点比较,包括:Linux环境编程(socket通信、文件IO操作、多路复用、信号安装、系统日志等)、数据库操作,关于树莓派和传感器的硬件知识等。
其中需要注意的地方也比较多:
1.服务器端异常断开后,客户端的数据怎么办?
2.如何实时监测服务器是否断开?
3.在延时间隔时间,是否可以进行其他操作?
4.数据库或者表是否已经存在?
5.有多个客户端连接怎么办?
6.如何判断本次发送的数据是新采集的数据,还是存在数据库里面的数据?
7.服务器端是否需要为每个客户端创建一个表?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。