๐ค ์ค์ต ๋ชฉํ
์ด์ ์ฑํ
์๋ฒ, ์ฑํ
ํด๋ผ์ด์ธํธ ํ๋ก๊ทธ๋จ์ ์ด์ด IoT ์๋ฒ, ํด๋ผ์ด์ธํธ ์ค์ต์ ์งํํ์์ต๋๋ค.
์ฑํ
์๋ฒ, ์ฑํ
ํด๋ผ์ด์ธํธ ๋ด์ฉ -> https://toby12.tistory.com/53
- iot_server, iot_client ํ๋ก๊ทธ๋จ ์์ฑ
- ํ๋ก๊ทธ๋จ ๋น๋
- ์ผ์, ๋๋ฐ์ด์ค ๋ฐ์ดํฐ ๋ฒ ์ด์ค ๊ตฌ์ถ
- ํด๋ผ์ด์ธํธ -> ์๋ฒ ์ผ์ ๋ฐ์ดํฐ ์กฐํ ์์ฒญ ๋ฐ ํ์ธ
- ํด๋ผ์ด์ธํธ -> ์๋ฒ ๋๋ฐ์ด์ค ์ค์ ์ ๋ฐ์ดํธ ์์ฒญ ๋ฐ ํ์ธ
๐ค ์์ธ ๊ธฐ๋ฅ
์๋ฒ
- ์์ผ ๋ฐ ์ค๋ ๋ ์ด๊ธฐํ:
- ์๋ฒ ์์ผ ์์ฑ ๋ฐ ์ด๊ธฐํ
- ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐ์ ์ฒ๋ฆฌํ๋ ์ค๋ ๋๋ฅผ ์์ฑ
- ํด๋ผ์ด์ธํธ ๊ด๋ฆฌ:
- ์ต๋ 32๊ฐ์ ํด๋ผ์ด์ธํธ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ ๋ฐฐ์ด๊ณผ ํด๋น ํด๋ผ์ด์ธํธ ์๋ฅผ ์ถ์ ํ๋ ๋ณ์ ์ค์
- ํด๋ผ์ด์ธํธ์ ID ๋ฐ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฏธ๋ฆฌ ๋ฑ๋ก๋ ์ ๋ณด์ ๋น๊ตํ์ฌ ์ธ์ฆ
- ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ:
- ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ ์ํ๋ฉด ์ค๋ ๋๋ฅผ ์์ฑํ์ฌ ํด๋ผ์ด์ธํธ์ ํต์ ์ ๋ด๋น
- MySQL ์ฐ๋:
- MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐํ๊ณ ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์กฐํ ๋ฐ ์ ๋ฐ์ดํธ
- "sensor" ๋ฐ "device" ํ ์ด๋ธ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ํด๋ผ์ด์ธํธ์๊ฒ ์ ์ก
- ํด๋ผ์ด์ธํธ ๊ฐ ๋ฉ์์ง ์ ์ก:
- ํด๋ผ์ด์ธํธ ๊ฐ ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์๋ ๊ธฐ๋ฅ ๊ตฌํ
- ํน์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฉ์์ง๋ฅผ ์ ์กํ ์ ์์
- ํด๋ผ์ด์ธํธ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ฉด ํด๋น ๋ฐ์ดํฐ๋ฅผ ์กฐํํ์ฌ ์ ์ก
- ๋ฐ์ดํฐ ์
๋ฐ์ดํธ:
- ํด๋ผ์ด์ธํธ๊ฐ "SET DEVICE" ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ฉด MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํด๋น ๋๋ฐ์ด์ค ๊ฐ์ ์ ๋ฐ์ดํธ
- ๋ฎคํ
์ค ์ฌ์ฉ:
- ๋ฎคํ ์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋์์ ์ฌ๋ฌ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ ๊ทผํ๋ ๊ฒ์ ์ ์ด.
ํด๋ผ์ด์ธํธ
- ์์ผ ๋ฐ ์ค๋ ๋ ์ด๊ธฐํ:
- ์๋ฒ์ ์ ์ํ๊ธฐ ์ํด ์์ผ์ ์์ฑํ๊ณ ์ด๊ธฐํ.
- ์ฐ๊ฒฐ ๋ฐ ๋ก๊ทธ์ธ:
- ์๋ฒ์ ์ ์ํ ํ, ๋ฏธ๋ฆฌ ์ง์ ๋ ID์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ.
- ๋ฉ์์ง ์ก์์ :
- ์ฌ์ฉ์๊ฐ ํ์ค ์ ๋ ฅ์ ํตํด ๋ฉ์์ง๋ฅผ ์ ๋ ฅํ๋ฉด ์๋ฒ๋ก ์ ์ก.
- ์๋ฒ๋ก๋ถํฐ ์์ ํ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅ.
- ์ค๋ ๋ ์์ฑ:
- ๋ฉ์์ง ์ ์ก ๋ฐ ์์ ์ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ฐ๊ฐ์ ๊ธฐ๋ฅ์ ์ํํ๋ ๋ ๊ฐ์ ์ค๋ ๋ ์์ฑ.
- 'quit' ๋ช
๋ น์ด ์ฒ๋ฆฌ:
- ์ฌ์ฉ์๊ฐ 'quit'์ ์ ๋ ฅํ๋ฉด ํด๋ผ์ด์ธํธ๊ฐ ์ข ๋ฃ๋๋๋ก ์ค์ .
- ๋ฉ์์ง ํฌ๋งท ์ฒ๋ฆฌ:
- ์ ๋ ฅ๋ ๋ฉ์์ง๋ฅผ ์๋ฒ์ ์ ์กํ๊ธฐ ์ ์ ํฌ๋งท์ ๋ง๊ฒ ๊ฐ๊ณต.
- ๋น๋ฐ๋ฒํธ ์ ์ก:
- ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ฐ๊ฒฐ๋๋ฉด ๋จผ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ์ก.
๐ค ์ค์ต ๊ฒฐ๊ณผ
iot client ํ๋ก๊ทธ๋จ ์์ฑ
- iot_server.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <pthread.h> #include <sys/stat.h> #include <fcntl.h> #include <dirent.h> #include <sys/time.h> #include <time.h> #include <errno.h> #include <mysql/mysql.h> #include <ctype.h> #define BUF_SIZE 200 #define MAX_CLNT 32 #define ID_SIZE 10 #define ARR_CNT 5 #define DEBUG // ๋ฉ์์ง ์ ๋ณด ๊ตฌ์กฐ์ฒด typedef struct { int fd; // ํ์ผ ์๋ณ์ char *from; // ๋ณด๋ธ ์ฌ๋ ID char *to; // ๋ฐ๋ ์ฌ๋ ID char *msg; // ๋ฉ์์ง ๋ด์ฉ int len; // ๋ฉ์์ง ๊ธธ์ด int is_sent; // ์ ์ก ์ฌ๋ถ ํ๋๊ทธ } MSG_INFO; // ํด๋ผ์ด์ธํธ ์ ๋ณด ๊ตฌ์กฐ์ฒด typedef struct { int index; // ํด๋ผ์ด์ธํธ ์ธ๋ฑ์ค int fd; // ํ์ผ ์๋ณ์ char ip[20]; // ํด๋ผ์ด์ธํธ IP ์ฃผ์ char id[ID_SIZE]; // ํด๋ผ์ด์ธํธ ID char pw[ID_SIZE]; // ํด๋ผ์ด์ธํธ ๋น๋ฐ๋ฒํธ } CLIENT_INFO; void *clnt_connection(void *arg); // ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ์ฒ๋ฆฌ ํจ์ void send_msg(MSG_INFO *msg_info, CLIENT_INFO *first_client_info); // ๋ฉ์์ง ์ ์ก ํจ์ void error_handling(char *msg); // ์ค๋ฅ ์ฒ๋ฆฌ ํจ์ void log_file(char *msgstr); // ๋ก๊ทธ ํ์ผ ์์ฑ ํจ์ void init_mysql(); // MySQL ์ด๊ธฐํ ํจ์ void send_data_to_client(int client_fd, char *name, char *request_type); // ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ ์ ์ก ํจ์ void find_data(int client_fd, char *name, char *request_type); // ๋ฐ์ดํฐ ์ฐพ๊ธฐ ํจ์ char *trim(char *str); // ๋ฌธ์์ด ์ ๋์ ๊ณต๋ฐฑ ์ ๊ฑฐ ํจ์ int clnt_cnt = 0; // ํ์ฌ ์ฐ๊ฒฐ๋ ํด๋ผ์ด์ธํธ ์ pthread_mutex_t mutx; // ๋ฎคํ ์ค ์ ์ธ MYSQL *conn; // MySQL ์ฐ๊ฒฐ ๊ฐ์ฒด int main(int argc, char *argv[]) { int serv_sock, clnt_sock; struct sockaddr_in serv_adr, clnt_adr; int clnt_adr_sz; int sock_option = 1; pthread_t t_id[MAX_CLNT] = {0}; int str_len = 0; int i; char idpasswd[(ID_SIZE * 2) + 3]; char *pToken; char *pArray[ARR_CNT] = {0}; char msg[BUF_SIZE]; // ์ด๊ธฐ ํด๋ผ์ด์ธํธ ์ ๋ณด ๋ฐฐ์ด CLIENT_INFO client_info[MAX_CLNT] = { {0, -1, "", "KHJ_LIN", "PASSWD"}, {0, -1, "", "KHJ_SQL", "PASSWD"}, {0, -1, "", "3", "PASSWD"}, {0, -1, "", "32", "PASSWD"}}; // ํฌํธ ๋ฒํธ๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ง ์์์ ์ ์ข ๋ฃ if (argc != 2) { printf("Usage : %s <port>\n", argv[0]); exit(1); } fputs("IoT Server Start!!\n", stdout); init_mysql(); // MySQL ์ด๊ธฐํ // ๋ฎคํ ์ค ์ด๊ธฐํ if (pthread_mutex_init(&mutx, NULL)) error_handling("mutex init error"); // ์์ผ ์์ฑ serv_sock = socket(PF_INET, SOCK_STREAM, 0); // ์๋ฒ ์ฃผ์ ๊ตฌ์กฐ์ฒด ์ด๊ธฐํ memset(&serv_adr, 0, sizeof(serv_adr)); serv_adr.sin_family = AF_INET; serv_adr.sin_addr.s_addr = htonl(INADDR_ANY); serv_adr.sin_port = htons(atoi(argv[1])); // ์์ผ ์ต์ ์ค์ setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, (void *)&sock_option, sizeof(sock_option)); // ๋ฐ์ธ๋ฉ ์ฒ๋ฆฌ if (bind(serv_sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) == -1) error_handling("bind() error"); // ๋ฆฌ์ค๋ ์ฒ๋ฆฌ if (listen(serv_sock, 5) == -1) error_handling("listen() error"); // ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ๋๊ธฐ ๋ฐ ์ฒ๋ฆฌ while (1) { clnt_adr_sz = sizeof(clnt_adr); clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_adr, &clnt_adr_sz); // ํด๋ผ์ด์ธํธ ์๊ฐ ์ต๋ ํด๋ผ์ด์ธํธ ์๋ฅผ ์ด๊ณผํ๋ฉด ์ฐ๊ฒฐ ๊ฑฐ๋ถ if (clnt_cnt >= MAX_CLNT) { printf("socket full\n"); shutdown(clnt_sock, SHUT_WR); continue; } else if (clnt_sock < 0) { perror("accept()"); continue; } // ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ID ๋ฐ ๋น๋ฐ๋ฒํธ ์์ str_len = read(clnt_sock, idpasswd, sizeof(idpasswd)); idpasswd[str_len] = '\0'; // ID ๋ฐ ๋น๋ฐ๋ฒํธ ์ฒ๋ฆฌ if (str_len > 0) { i = 0; pToken = strtok(idpasswd, "[:]"); while (pToken != NULL) { pArray[i] = pToken; if (i++ >= ARR_CNT) break; pToken = strtok(NULL, "[:]"); } // ๋ฑ๋ก๋ ํด๋ผ์ด์ธํธ ์ ๋ณด์์ ID์ ๋น๋ฐ๋ฒํธ ์ผ์น ์ฌ๋ถ ํ์ธ for (i = 0; i < MAX_CLNT; i++) { if (!strcmp(client_info[i].id, pArray[0])) { if (client_info[i].fd != -1) { // ์ด๋ฏธ ๋ก๊ทธ์ธํ ๊ฒฝ์ฐ sprintf(msg, "[%s] Already logged!\n", pArray[0]); write(clnt_sock, msg, strlen(msg)); log_file(msg); shutdown(clnt_sock, SHUT_WR); // MCU ํด๋ผ์ด์ธํธ์ ๊ฒฝ์ฐ ๊ธฐ์กด ์ฐ๊ฒฐ ๋๊ธฐ shutdown(client_info[i].fd, SHUT_WR); client_info[i].fd = -1; break; } // ID์ ๋น๋ฐ๋ฒํธ ์ผ์น ์ ํด๋ผ์ด์ธํธ ์ ๋ณด ์ ๋ฐ์ดํธ if (!strcmp(client_info[i].pw, pArray[1])) { strcpy(client_info[i].ip, inet_ntoa(clnt_adr.sin_addr)); pthread_mutex_lock(&mutx); client_info[i].index = i; client_info[i].fd = clnt_sock; clnt_cnt++; pthread_mutex_unlock(&mutx); sprintf(msg, "[%s] New connected! (ip:%s,fd:%d,sockcnt:%d)\n", pArray[0], inet_ntoa(clnt_adr.sin_addr), clnt_sock, clnt_cnt); log_file(msg); write(clnt_sock, msg, strlen(msg)); // ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ์ ๋ํ ์ค๋ ๋ ์์ฑ ๋ฐ ๋ถ๋ฆฌ pthread_create(t_id + i, NULL, clnt_connection, (void *)(client_info + i)); pthread_detach(t_id[i]); break; }}} // ๋ฑ๋ก๋ ํด๋ผ์ด์ธํธ๊ฐ ์๋ ๊ฒฝ์ฐ ์ฐ๊ฒฐ ๊ฑฐ๋ถ if (i == MAX_CLNT) { sprintf(msg, "[%s] Authentication Error!\n", pArray[0]); write(clnt_sock, msg, strlen(msg)); log_file(msg); shutdown(clnt_sock, SHUT_WR); } } else shutdown(clnt_sock, SHUT_WR); } return 0; } // MySQL ์ด๊ธฐํ ํจ์ void init_mysql() { conn = mysql_init(NULL); if (conn == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(1); } else if (mysql_real_connect(conn, "127.0.0.1", "iot", "pwiot", "iotdb", 0, NULL, 0) == NULL) { fprintf(stderr, "mysql_real_connect() failed\n"); mysql_close(conn); exit(1); } else { fputs("MYSQL Start!!\n", stdout); }} // ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ ์กฐํ void find_data(int client_fd, char *name, char *request_type) { MYSQL_RES *result; MYSQL_ROW row; char query[BUF_SIZE]; char data_info[BUF_SIZE]; // MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ if (strcmp(request_type, "[ALLMSG]GET SENSOR") == 0) { sprintf(query, "SELECT illu, temp, humi, date, time FROM sensor WHERE name='%s' " "ORDER BY id DESC LIMIT 1", name); if (mysql_query(conn, query)) { fprintf(stderr, "SELECT query failed: %s\n", mysql_error(conn)); return; } result = mysql_store_result(conn); if (result == NULL) { fprintf(stderr, "mysql_store_result() failed\n"); return; } row = mysql_fetch_row(result); if (row != NULL) { int illu = atoi(row[0]); int temp = atoi(row[1]); int humi = atoi(row[2]); char date[BUF_SIZE]; char time[BUF_SIZE]; strncpy(date, row[3], BUF_SIZE); strncpy(time, row[4], BUF_SIZE); size_t remaining_space = BUF_SIZE - 1; remaining_space -= snprintf( data_info, remaining_space, "[SENSOR_DATA] %s: Illuminance=%d, Temperature=%d, Humidity=%d, " "Date=%s, Time=%s\n", name, illu, temp, humi, date, time); } mysql_free_result(result); } else if (strcmp(request_type, "[ALLMSG]GET DEVICE") == 0) { sprintf(query, "SELECT value, date, time FROM device WHERE name='%s' ORDER BY id " "DESC LIMIT 1", name); if (mysql_query(conn, query)) { fprintf(stderr, "SELECT query failed: %s\n", mysql_error(conn)); return; } // MySQL์กฐํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ ํฌ์ธํฐ ๋ณ์ result = mysql_store_result(conn); // ๊ฒฐ๊ณผ๊ฐ ์๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ข ๋ฃ if (result == NULL) { fprintf(stderr, "mysql_store_result() failed\n"); return; } // ๊ฒฐ๊ณผ๋ฅผ ํ์ผ๋ก ์ ์ฅ row = mysql_fetch_row(result); // ๊ฐ์ ธ์จ ํ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ if (row != NULL) { // ํ์์ ์ฒซ ๋ฒ์งธ ์ด ๊ฐ์ ์ ์๋ก ๋ณํ int value = atoi(row[0]); // ํ์์ ๋ ๋ฒ์งธ, ์ธ ๋ฒ์งธ ์ด ๊ฐ์ ๋ฌธ์์ด๋ก ๋ณต์ฌ char date[BUF_SIZE]; char time[BUF_SIZE]; strncpy(date, row[1], BUF_SIZE); strncpy(time, row[2], BUF_SIZE); // ๋ฐ์ดํฐ ์ ๋ณด ๋ฌธ์์ด์ ์ ์ฅํ ๋ฒํผ ๋ฐ ๋จ์ ๊ณต๊ฐ ๊ณ์ฐ size_t remaining_space = BUF_SIZE - 1; // ๋ฐ์ดํฐ ์ ๋ณด๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํ์ฌ ๋ฒํผ์ ์ ์ฅ remaining_space -= snprintf(data_info, remaining_space, "[DEVICE_INFO] %s: Value=%d, Date=%s, Time=%s\n", name, value, date, time); } mysql_free_result(result); } else { fprintf(stderr, "Invalid request type: %s\n", request_type); return; } // ๋ฐ์ดํฐ ์ ๋ณด๋ฅผ ํด๋ผ์ด์ธํธ์ ์ ์ก write(client_fd, data_info, strlen(data_info)); } // ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐ์ดํฐ ์ ์ก void send_data_to_client(int client_fd, char *name, char *request_type) { if (strcmp(request_type, "[ALLMSG]GET SENSOR") == 0) { find_data(client_fd, name,request_type); } else if (strcmp(request_type, "[ALLMSG]GET DEVICE") == 0) { find_data(client_fd, name,request_type); } else { fprintf(stderr, "Invalid request type: %s\n", request_type); }} // ํด๋ผ์ด์ธํธ ์ฐ๋ ๋ ํจ์ void *clnt_connection(void *arg) { // ์ ๋ฌ๋ฐ์ ์ธ์๋ฅผ ํด๋ผ์ด์ธํธ ์ ๋ณด ๊ตฌ์กฐ์ฒด๋ก ํ๋ณํ CLIENT_INFO *client_info = (CLIENT_INFO *)arg; // ๋ณ์ ๋ฐ ๋ฐฐ์ด ์ด๊ธฐํ int str_len = 0; int index = client_info->index; char msg[BUF_SIZE]; char to_msg[MAX_CLNT * ID_SIZE + 1]; int i = 0; char *pToken; char *pArray[ARR_CNT] = {0}; char strBuff[130] = {0}; char sql_cmd[BUF_SIZE]; // ์ฟผ๋ฆฌ ๋ช ๋ น๋ฌธ ์ ์ฅ์ฉ ๋ฐฐ์ด int res; // ์ฟผ๋ฆฌ ์คํ ๊ฒฐ๊ณผ ์ ์ฅ์ฉ ๋ณ์ int *sock; // ์์ผ ์ ๋ณด ์ ์ฅ์ฉ ๋ณ์ // ๋ฉ์์ง ์ ๋ณด ๋ฐ ์ฒซ ๋ฒ์งธ ํด๋ผ์ด์ธํธ ์ ๋ณด ๊ตฌ์กฐ์ฒด ์ด๊ธฐํ MSG_INFO msg_info; CLIENT_INFO *first_client_info; first_client_info = (CLIENT_INFO *)((void *)client_info - (void *)(sizeof(CLIENT_INFO) * index)); // ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ๊ณ์ ์ฝ์ด์ค๋ ๋ฃจํ while (1) { // ๋ฒํผ ์ด๊ธฐํ ๋ฐ ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฉ์์ง ์ฝ๊ธฐ memset(msg, 0x0, sizeof(msg)); str_len = read(client_info->fd, msg, sizeof(msg) - 1); // ๋ฉ์์ง ๊ธธ์ด๊ฐ 0 ์ดํ์ธ ๊ฒฝ์ฐ ์ฐ๊ฒฐ ์ข ๋ฃ if (str_len <= 0) break; // ๋ฌธ์์ด ๋์ null ์ถ๊ฐ msg[str_len] = '\0'; // ๋ฐ์ ๋ฉ์์ง ์ถ๋ ฅ printf("%s: %s", client_info->id, msg); // [ALLMSG]GET SENSOR ๋ฉ์์ง์ธ ๊ฒฝ์ฐ SENSOR ๋ฐ์ดํฐ ์ ์ก if (strcmp(trim(msg), "[ALLMSG]GET SENSOR") == 0) { send_data_to_client(client_info->fd, client_info->id, "[ALLMSG]GET SENSOR"); } // [ALLMSG]GET DEVICE ๋ฉ์์ง์ธ ๊ฒฝ์ฐ DEVICE ๋ฐ์ดํฐ ์ ์ก else if (strcmp(trim(msg), "[ALLMSG]GET DEVICE") == 0) { send_data_to_client(client_info->fd, client_info->id, "[ALLMSG]GET DEVICE"); } // [ALLMSG]SET DEVICE ๋ฉ์์ง์ธ ๊ฒฝ์ฐ ๊ฐ ์ ๋ฐ์ดํธ else if (strstr(msg, "[ALLMSG]SET DEVICE")) { // SET DEVICE ๋ฉ์์ง ํ์ฑ int value; char device[20]; // ๋ณ์ ๋ฐ ๋ฐฐ์ด ์ด๊ธฐํ memset(sql_cmd, 0, sizeof(sql_cmd)); res = 0; // SET DEVICE ๋ช ๋ น ๋ฉ์์ง ํ์ฑ if (sscanf(msg, "[ALLMSG]SET DEVICE %d", &value) == 1) { // MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๋ฐ์ดํธ๋ฅผ ์ํ SQL ๋ช ๋ น์ด ์์ฑ sprintf(sql_cmd, "UPDATE device SET value=%d, date=CURDATE(), time=CURTIME() WHERE name='%s'", value, client_info->id); // SQL ๋ช ๋ น์ด ์คํ int res = mysql_query(conn, sql_cmd); // ์ ๋ฐ์ดํธ ์ฑ๊ณตํ ๊ฒฝ์ฐ if (!res) { printf("[%s] ๋๋ฐ์ด์ค ๊ฐ์ด %d๋ก ์ ๋ฐ์ดํธ๋์์ต๋๋ค\n", client_info->id, value); } // ์ ๋ฐ์ดํธ ์คํจํ ๊ฒฝ์ฐ else { fprintf(stderr, "๋๋ฐ์ด์ค ๊ฐ ์ ๋ฐ์ดํธ ์ค๋ฅ: %s\n", mysql_error(conn)); }} // ์๋ชป๋ SET ๋ช ๋ น ํ์์ธ ๊ฒฝ์ฐ else { fprintf(stderr, "์ค๋ฅ: ์๋ชป๋ SET ๋ช ๋ น ํ์\n"); }} // ๋ฉ์์ง๋ฅผ [:]๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ถ๋ฆฌํ์ฌ ๋ฐฐ์ด์ ์ ์ฅ pToken = strtok(msg, "[:]"); i = 0; while (pToken != NULL) { pArray[i] = pToken; if (i++ >= ARR_CNT) break; pToken = strtok(NULL, "[:]"); } // ๋ฉ์์ง ์ ๋ณด ๊ตฌ์กฐ์ฒด์ ์ ๋ณด ์ ์ฅ msg_info.fd = client_info->fd; msg_info.from = client_info->id; msg_info.to = pArray[0]; sprintf(to_msg, "[%s]%s", msg_info.from, pArray[1]); msg_info.msg = to_msg; msg_info.len = strlen(to_msg); // ๋ฉ์์ง ๋ฐ์ ์ฌ๋ถ ์ด๊ธฐํ msg_info.is_sent = 0; // ๋ก๊ทธ ํ์ผ์ ๋ฉ์์ง ๊ธฐ๋ก log_file(strBuff); // send_msg(&msg_info, first_client_info); } // ํด๋ผ์ด์ธํธ ์์ผ ์ข ๋ฃ close(client_info->fd); // ์ฐ๊ฒฐ ์ข ๋ฃ ๋ฉ์์ง ๊ธฐ๋ก sprintf(strBuff, "Disconnect ID:%s (ip:%s,fd:%d,sockcnt:%d)\n", client_info->id, client_info->ip, client_info->fd, clnt_cnt - 1); log_file(strBuff); // ๋ฎคํ ์ค๋ฅผ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ ์ ๊ฐฑ์ pthread_mutex_lock(&mutx); clnt_cnt--; client_info->fd = -1; pthread_mutex_unlock(&mutx); // ์ฐ๋ ๋ ์ข ๋ฃ return 0; } // ๋ฌธ์์ด ์ ๋์ ๊ณต๋ฐฑ์ ์ ๊ฑฐํ๋ ํจ์ char* trim(char* str) { char* end; // ๋ฌธ์์ด ์์์ ๊ณต๋ฐฑ ์ ๊ฑฐ while (isspace(*str)) str++; // ๋น ๋ฌธ์์ด์ธ ๊ฒฝ์ฐ ๋ฌธ์์ด ๋์ ๊ณต๋ฐฑ ์ ๊ฑฐ if (*str == 0) return str; end = str + strlen(str) - 1; while (end > str && isspace(*end)) end--; // NULL ์ถ๊ฐํ์ฌ ๋ฌธ์์ด ์ข ๋ฃ *(end + 1) = 0; return str; } // ๋ฉ์์ง ์ ์ก ํจ์ void send_msg(MSG_INFO *msg_info, CLIENT_INFO *first_client_info) { int i = 0; // ์ ์ฒด ๋๋ ํน์ ํด๋ผ์ด์ธํธ์ ๋ฉ์์ง ์ ์ก if (!strcmp(msg_info->to, "[ALLMSG]") || !strcmp(msg_info->to, "[IDLIST]")) { for (i = 0; i < MAX_CLNT; i++) { if ((first_client_info + i)->fd != -1) { write((first_client_info + i)->fd, msg_info->msg, msg_info->len); }} // ๋ค์ ๋ฉ์์ง๋ฅผ ์ํด is_sent๋ฅผ 0์ผ๋ก ์ด๊ธฐํ if ((msg_info->fd != -1) && (msg_info->is_sent == 0)) { msg_info->is_sent = 1; } return; } // ํน์ ํด๋ผ์ด์ธํธ์ ๋ฉ์์ง ์ ์ก else { if ((msg_info->fd != -1) && (msg_info->is_sent == 0)) { write(msg_info->fd, msg_info->msg, msg_info->len); msg_info->is_sent = 1; }}} // ์๋ฌ ์ฒ๋ฆฌ ํจ์ void error_handling(char *msg) { fputs(msg, stderr); fputc('\n', stderr); exit(1); } // ๋ก๊ทธ ํ์ผ์ ๋ฉ์์ง ๊ธฐ๋ก ํจ์ void log_file(char *msgstr) { fputs(msgstr, stdout); }
- iot_client_sensor.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <pthread.h> #include <signal.h> #define BUF_SIZE 100 #define NAME_SIZE 20 #define ARR_CNT 5 // ๋ฉ์์ง๋ฅผ ์ ์กํ๋ ์ค๋ ๋์ ์ญํ void* send_msg(void* arg); // ๋ฉ์์ง๋ฅผ ์์ ํ๋ ์ค๋ ๋์ ์ญํ void* recv_msg(void* arg); // ์๋ฌ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ ํ๋ก๊ทธ๋จ์ ์ข ๋ฃํ๋ ํจ์ void error_handling(char* msg); // ์ฌ์ฉ์์ ์ด๋ฆ๊ณผ ๋ฉ์์ง๋ฅผ ์ ์ฅํ๋ ์ ์ญ ๋ณ์ char name[NAME_SIZE] = "[Default]"; char msg[BUF_SIZE]; int main(int argc, char* argv[]) { int sock; struct sockaddr_in serv_addr; pthread_t snd_thread, rcv_thread; void* thread_return; // ํ๋ก๊ทธ๋จ ์คํ ์ IP, ํฌํธ, ์ด๋ฆ์ ์ ๋ฌํ์ง ์์์ ๊ฒฝ์ฐ ์ฌ์ฉ๋ฒ ์ถ๋ ฅ if (argc != 4) { printf("Usage : %s <IP> <port> <name>\n", argv[0]); exit(1); } // ์ ๋ฌ๋ฐ์ ์ด๋ฆ์ ์ ์ญ ๋ณ์์ ์ ์ฅ sprintf(name, "%s", argv[3]); // ์์ผ ์์ฑ sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) error_handling("socket() error"); // ์๋ฒ ์ฃผ์ ๊ตฌ์กฐ์ฒด ์ด๊ธฐํ memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(argv[1]); serv_addr.sin_port = htons(atoi(argv[2])); // ์๋ฒ์ ์ฐ๊ฒฐ if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) error_handling("connect() error"); // ๋น๋ฐ๋ฒํธ ๋ฉ์์ง๋ฅผ ์์ฑํ์ฌ ์๋ฒ์ ์ ์ก sprintf(msg, "[%s:PASSWD]", name); write(sock, msg, strlen(msg)); // ๋ฉ์์ง ์ ์ก ๋ฐ ์์ ์ ์ํ ์ค๋ ๋ ์์ฑ pthread_create(&rcv_thread, NULL, recv_msg, (void*)&sock); pthread_create(&snd_thread, NULL, send_msg, (void*)&sock); // ์ค๋ ๋ ์ข ๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆผ pthread_join(snd_thread, &thread_return); pthread_join(rcv_thread, &thread_return); // ์์ผ ์ข ๋ฃ close(sock); return 0; } // ๋ฉ์์ง๋ฅผ ์ ์กํ๋ ์ค๋ ๋์ ์ญํ void* send_msg(void* arg) { int* sock = (int*)arg; int str_len; char name_msg[NAME_SIZE + BUF_SIZE + 2]; while (1) { // ๋ฉ์์ง ์ด๊ธฐํ memset(msg, 0, sizeof(msg)); name_msg[0] = '\0'; // ํ์ค ์ ๋ ฅ(STDIN)์ ์ํ๋ฅผ ํ์ธํ๊ณ 10ms๋ง๋ค ๋๊ธฐ fd_set read_fds; FD_ZERO(&read_fds); FD_SET(STDIN_FILENO, &read_fds); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 10000; // 10ms๋ก ์ค์ // ํ์ค ์ ๋ ฅ ์ํ ๋ณ๊ฒฝ์ ๊ธฐ๋ค๋ฆผ if (select(STDIN_FILENO + 1, &read_fds, NULL, NULL, &tv) > 0) { // ํ์ค ์ ๋ ฅ์ผ๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ์ฝ์ด์ด if (FD_ISSET(STDIN_FILENO, &read_fds)) { fgets(msg, BUF_SIZE, stdin); // 'quit' ๋ฉ์์ง๋ฅผ ์ ๋ ฅํ๋ฉด ์์ผ ์ข ๋ฃ if (!strncmp(msg, "quit\n", 5)) { *sock = -1; return NULL; } // ๋ฉ์์ง๊ฐ '['๋ก ์์ํ์ง ์๋ ๊ฒฝ์ฐ '[ALLMSG]' ํ๊ทธ๋ฅผ ์ถ๊ฐ else if (msg[0] != '[') { strcat(name_msg, "[ALLMSG]"); strcat(name_msg, msg); } // ๋ฉ์์ง๊ฐ '['๋ก ์์ํ๋ ๊ฒฝ์ฐ ๊ทธ๋๋ก ์ฌ์ฉ else { strcpy(name_msg, msg); } // ์๋ฒ๋ก ๋ฉ์์ง ์ ์ก if (write(*sock, name_msg, strlen(name_msg)) <= 0) { *sock = -1; return NULL; }}}}} // ๋ฉ์์ง๋ฅผ ์์ ํ๋ ์ค๋ ๋์ ์ญํ void* recv_msg(void* arg) { int* sock = (int*)arg; char name_msg[NAME_SIZE + BUF_SIZE + 1]; int str_len; while (1) { // ๋ฉ์์ง ์ด๊ธฐํ memset(name_msg, 0x0, sizeof(name_msg)); // ์๋ฒ๋ก๋ถํฐ ๋ฉ์์ง ์์ str_len = read(*sock, name_msg, NAME_SIZE + BUF_SIZE); if (str_len <= 0) { // ์๋ฌ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ์ฐ๊ฒฐ์ด ๋๊ธด ๊ฒฝ์ฐ ์์ผ ์ข ๋ฃ *sock = -1; return NULL; } name_msg[str_len] = 0; // ์์ ๋ ๋ฉ์์ง ์ถ๋ ฅ printf("%s", name_msg); }} // ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ๋ฐ ํ๋ก๊ทธ๋จ ์ข ๋ฃ void error_handling(char* msg) { fputs(msg, stderr); fputc('\n', stderr); exit(1); }
ํ๋ก๊ทธ๋จ ๋น๋
1. iot_server, iot_client ๋น๋ ๊ฒฐ๊ณผ
๋ฐ์ดํฐ ๋ฒ ์ด์ค ์์ฑ ๋ฐ ๋ฐ์ดํฐ ์ฝ์
๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ๋ด์ฉ์ ํด๋น ์นดํ
๊ณ ๋ฆฌ์ ์ ๋ฆฌํ์์ต๋๋ค. -> https://toby12.tistory.com/category/database
1. iotdb ์์ฑ
create database iotdb character set utf8;
2. sensor ํ
์ด๋ธ ์์ฑ
create table sensor (id int not null auto_increment, name varchar(20), date date, time time,
illu int, temp float, humi float, primary key (id)) default character set=utf8;
3. sensor ํ ์ด๋ธ ๋ฐ์ดํฐ ์ฝ์
insert into sensor (name, date, time, illu, temp, humi) value ("KHJ_SQL", now(),now(), 60, 20, 40);
4. device ํ ์ด๋ธ ์์ฑ
create table device (id int not null, name varchar(20), date date, time time, value int,
info varchar(20), primary key (id) ) default charset=utf8;
์๋ฒ, ํด๋ผ์ด์ธํธ ํ๋ก๊ทธ๋จ ์คํ
1. ์๋ฒ ํ๋ก๊ทธ๋จ
2. ํด๋ผ์ด์ธํธ ํ๋ก๊ทธ๋จ
ํด๋ผ์ด์ธํธ -> ์๋ฒ ์ผ์ ๋ฐ์ดํฐ ์กฐํ ์์ฒญ ๋ฐ ํ์ธ
1. GET SENSOR
2. GET DEIVCE
ํด๋ผ์ด์ธํธ -> ์๋ฒ ๋๋ฐ์ด์ค ์ค์ ์ ๋ฐ์ดํธ ์์ฒญ ๋ฐ ํ์ธ
SET Device 9 ๋ฉ์ธ์ง๋ฅผ ์๋ฒ์ ๋ณด๋ด์ด ํด๋น ์ฌ์ฉ์์ ๋๋ฐ์ด์ค์ ๋ณด๋ฅผ ์ ๋ฐ์ดํธ๋จ ํ์ธ
'embedded' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Simulink ์ ๋ฆฌ (0) | 2024.01.11 |
---|---|
MATLAB ์ ๋ฆฌ (0) | 2024.01.08 |
[ubuntu] ์์ผ ํต์ ์ฑํ ์๋ฒ (0) | 2023.11.23 |
[ubuntu] ์์ผ ํต์ ๋ฐ์ดํฐ ์ ์ก ๋ฐ ์ ์ฅ (0) | 2023.11.20 |
[protocol] bxCAN ์ด๋ก ์ ๋ฆฌ (0) | 2023.10.29 |