๐ฌ ์์ผ ํต์ ์ด๋??
์๋ ๊ธ์์ ์ ๋ฆฌํ์์ต๋๋ค.
๐ฌ ์ค์ต ๋ชฉํ
1. ์์ผ ํต์ ์ ์ด์ฉํ ์ฑํ ํ๋ก๊ทธ๋จ ์์ฑ
โป ์ฑํ ์๋ฒ โป
- ์๋ฒ ์ด๊ธฐํ ๋ฐ ์์ผ ์์ฑ
- ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ํฌํธ ๋ฒํธ๋ก ์๋ฒ ์ด๊ธฐํ ๋ฐ ์์ผ์ ์์ฑ
- ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ๋๊ธฐ ๋ฐ ์ธ์ฆ
- accept ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ฒฐ ์์ฒญ๋ฐ์ ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐ
- ํด๋ผ์ด์ธํธ๊ฐ ์ฐ๊ฒฐ๋๋ฉด, ID ๋ฐ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฐ์ ์ธ์ฆ ์ํ
- ํด๋ผ์ด์ธํธ ๊ด๋ฆฌ ๋ฐ ์ฐ๋ ๋ ์์ฑ
- ์ต๋ MAX_CLNT ๊ฐ์๊น์ง์ ํด๋ผ์ด์ธํธ๋ฅผ ๊ด๋ฆฌ
- ์๋ก์ด ํด๋ผ์ด์ธํธ๊ฐ ์ฐ๊ฒฐ๋๋ฉด, ์ฐ๋ ๋๋ฅผ ์์ฑํ์ฌ ํด๋น ํด๋ผ์ด์ธํธ์ ํต์ ์ ๋ด๋น
- ๋ฉ์์ง ์ ์ก
- send_msg ํจ์๋ฅผ ํตํด ํด๋ผ์ด์ธํธ์๊ฒ ๋ฉ์์ง๋ฅผ ์ ์ก
- 'ALLMSG'๋ผ๋ ํน๋ณํ ์์ ์์๊ฒ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฉ์์ง๋ฅผ ์ ์ก
- 'IDLIST' ์์ ์์๊ฒ๋ ํ์ฌ ์๋ฒ์ ์ฐ๊ฒฐ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ์ ID ๋ชฉ๋ก์ ์ ์ก
- ์ฐ๋ ๋ ํจ์ (clnt_connection)
- ํด๋ผ์ด์ธํธ ์ฐ๋ ๋ ํจ์๋ก, ํด๋ผ์ด์ธํธ์์ ํต์ ์ ๋ด๋น
- ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ์์ ํ๊ณ , ์ด๋ฅผ ์ฒ๋ฆฌํ์ฌ ๋ค๋ฅธ ํด๋ผ์ด์ธํธ์๊ฒ ์ ํ
โป ํด๋ผ์ด์ธํธ โป
- ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ๋ฐ ์์ผ ์์ฑ
- ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ์๋ฒ์ IP ์ฃผ์์ ํฌํธ ๋ฒํธ๋ก ์๋ฒ์ ์์ผ์ ์์ฑํ์ฌ ์ฐ๊ฒฐ์ ์๋
- ์ธ์ฆ
- ๋งค๊ฐ๋ณ์์ ์ง์ ํ ์ด๋ฆ์ผ๋ก ์๋ฒ์ ์ ์, ๋น๋ฐ๋ฒํธ๋ฅผ ํจ๊ป ์ ์กํ์ฌ ์ธ์ฆ์ ์ํํจ
- ๋ฉ์์ง ์ก์์
- ์ฌ์ฉ์๋ ํค๋ณด๋๋ก ๋ฉ์์ง๋ฅผ ์ ๋ ฅํ๊ณ , ์ด๋ฅผ ์๋ฒ์ ์ ์ก
- ์๋ฒ๋ก๋ถํฐ์ ๋ฉ์์ง๋ ๋ณ๋์ ์ฐ๋ ๋๋ฅผ ํตํด ์์ ๋์ด ํ๋ฉด์ ์ถ๋ ฅ๋จ
- ์ฐ๋ ๋ ํจ์ (send_msg, recv_msg)
- ๊ฐ๊ฐ ๋ฉ์์ง ์ก์ ๋ฐ ์์ ์ ๋ด๋นํ๋ ์ฐ๋ ๋ ํจ์์ด๋ค.
- send_msg ํจ์๋ ์ฌ์ฉ์์ ์ ๋ ฅ์ ์ฝ์ด ์๋ฒ๋ก ์ ์กํ๊ณ
- recv_msg ํจ์๋ ์๋ฒ๋ก๋ถํฐ์ ๋ฉ์์ง๋ฅผ ์์ ํ์ฌ ํ๋ฉด์ ์ถ๋ ฅํ
โป ์ถ๊ฐ ๋ด์ฉ โป
- ์ฐ๋ ๋ ์ฌ์ฉ
- ๊ฐ ํด๋ผ์ด์ธํธ๋ ๋ณ๋์ ์ฐ๋ ๋์์ ์ฒ๋ฆฌ๋๊ณ ์ด๋ฅผ ํตํด ์ฌ๋ฌ ํด๋ผ์ด์ธํธ์ ๋์์ ํต์ ํ ์ ์์ต๋๋ค.
- pthread ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉํฐ์ฐ๋ ๋ฉ์ ๊ตฌํํ์์ต๋๋ค.
- ๋ฎคํ
์ค ์ฌ์ฉ
- ์๋ฒ์์๋ ํด๋ผ์ด์ธํธ์ ์ฐ๊ฒฐ ๋ฐ ํด์ ์ ๋ฐ๋ฅธ ๊ณต์ ์์ ์ ๊ทผ์ ๋ณดํธํ๊ธฐ ์ํด ๋ฎคํ ์ค๋ฅผ ์ฌ์ฉ
- pthread_mutex_lock ๋ฐ pthread_mutex_unlock ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ํธ๋ฐฐ์ ๋ฅผ ๊ตฌํํ์์ต๋๋ค.
- ํด๋ผ์ด์ธํธ ๊ด๋ฆฌ
- ์๋ฒ์์๋ ์ต๋ MAX_CLNT ๊ฐ์ ํด๋ผ์ด์ธํธ๋ฅผ ๊ด๋ฆฌ
- ํด๋ผ์ด์ธํธ์ ์ํ๋ CLIENT_INFO ๊ตฌ์กฐ์ฒด๋ฅผ ํตํด ๊ด๋ฆฌ๋๋ฉฐ, ๊ฐ ํด๋ผ์ด์ธํธ๋ ID, IP ์ฃผ์, ์์ผ ์๋ณ์ ๋ฑ์
๊ฐ์ง๊ณ ์์ต๋๋ค.
- ๋ฉ์์ง ์ ์ก
- ์๋ฒ์์๋ ํน์ ์์ ์์๊ฒ ๋ฉ์์ง๋ฅผ ์ ์กํ๋ send_msg ํจ์๋ฅผ ๊ตฌํ
- ์์ ์๊ฐ 'ALLMSG'์ธ ๊ฒฝ์ฐ์๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฉ์์ง๋ฅผ ์ ํํ๊ณ , 'IDLIST'์ธ ๊ฒฝ์ฐ์๋
ํ์ฌ ์ ์ ์ค์ธ ํด๋ผ์ด์ธํธ์ ID ๋ชฉ๋ก์ ์ ์กํฉ๋๋ค.
2. make ํ์ผ๋ก ๋น๋
3. server, client ํ๋ก๊ทธ๋จ ์คํ
4. ๊ฒฐ๊ณผ ํ์ธ
๐ฌ ์ค์ต ๊ฒฐ๊ณผ
์์ผ ํต์ ์ ์ด์ฉํ ์ฑํ ํ๋ก๊ทธ๋จ ์์ฑ
1. client.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
char name[NAME_SIZE] = "[Default]"; // ํด๋ผ์ด์ธํธ์ ์ด๋ฆ
char msg[BUF_SIZE]; // ๋ฉ์์ง๋ฅผ ์ ์ฅํ๋ ๋ฒํผ
void *send_msg(void *arg);
void *recv_msg(void *arg);
void error_handling(char *msg);
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in serv_addr;
pthread_t snd_thread, rcv_thread;
void *thread_return;
// ๋งค๊ฐ๋ณ์๊ฐ 4๊ฐ๊ฐ ์๋ ์ ์๋ด ๋ฐ ์ข
๋ฃ(ํ๋ก๊ทธ๋จ, 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");
// ํด๋ผ์ด์ธํธ์ ์ด๋ฆ๊ณผ "PASSWD"๋ฅผ ์๋ฒ์ ์ ์ก
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);
// ์์ผ ๋ซ์ ํ ํ๋ก๊ทธ๋จ ์ข
๋ฃ
close(sock);
return 0;
}
// ๋ฉ์์ง๋ฅผ ์๋ฒ๋ก ์ ์กํ๋ ํจ์
void *send_msg(void *arg) {
int *sock = (int *)arg;
int str_len;
int ret;
fd_set initset, newset;
struct timeval tv;
char name_msg[NAME_SIZE + BUF_SIZE + 2];
// ํ์ผ ์ด๊ธฐํ
FD_ZERO(&initset);
FD_SET(STDIN_FILENO, &initset);
// ๋ฉ์์ง ์
๋ ฅ ๋๊ธฐ
fputs("Input a message! [ID]msg (Default ID:ALLMSG)\n", stdout);
while (1) {
memset(msg, 0, sizeof(msg));
name_msg[0] = '\0';
tv.tv_sec = 1;
tv.tv_usec = 0;
newset = initset;
ret = select(STDIN_FILENO + 1, &newset, NULL, NULL, &tv);
if (FD_ISSET(STDIN_FILENO, &newset)) {
// ์ฌ์ฉ์๋ก๋ถํฐ ๋ฉ์์ง ์
๋ ฅ ๋ฐ์
fgets(msg, BUF_SIZE, stdin);
// "quit"์ ์
๋ ฅํ๋ฉด ํด๋ผ์ด์ธํธ ์์ผ์ ์ข
๋ฃ
if (!strncmp(msg, "quit\n", 5)) {
*sock = -1;
return NULL;
} else if (msg[0] != '[') {
// ๋ฉ์์ง์ ์ฒซ ๊ธ์๊ฐ '['์ด ์๋๋ฉด "[ALLMSG]"๋ฅผ ์ถ๊ฐํ์ฌ ์ ์ก
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;
}}
if (ret == 0) {
// ํ์์์ ๋ฐ์ ์
if (*sock == -1)
return NULL;
}}}
// ์๋ฒ๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ์์ ํ๋ ํจ์
void *recv_msg(void *arg) {
int *sock = (int *)arg;
int i;
char *pToken;
char *pArray[ARR_CNT] = {0};
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;
// ์์ ํ ๋ฉ์์ง๋ฅผ ํ์ค ์ถ๋ ฅ์ ์ถ๋ ฅ
fputs(name_msg, stdout);
// ๋ฉ์์ง ํ์ฑ
/*
pToken = strtok(name_msg, "[:]");
i = 0;
while (pToken != NULL) {
pArray[i] = pToken;
if (++i >= ARR_CNT)
break;
pToken = strtok(NULL, "[:]");
}
printf("id:%s, msg:%s\n", pArray[0], pArray[1]);
*/
}}
// ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํ ํ๋ก๊ทธ๋จ์ ์ข
๋ฃํ๋ ํจ์
void error_handling(char *msg) {
fputs(msg, stderr);
fputc('\n', stderr);
exit(1);
}
2. 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>
#define BUF_SIZE 100
#define MAX_CLNT 32
#define ID_SIZE 10
#define ARR_CNT 5
#define DEBUG
// ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ ๋ฉ์์ง ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ๊ตฌ์กฐ์ฒด
typedef struct {
char fd;
char *from;
char *to;
char *msg;
int len;
} MSG_INFO;
// ํด๋ผ์ด์ธํธ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ๊ตฌ์กฐ์ฒด
typedef struct {
int index;
int fd;
char ip[20];
char id[ID_SIZE];
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);
int clnt_cnt = 0;
pthread_mutex_t mutx;
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,"","4","PASSWD"}, {0,-1,"","5","PASSWD"}, \
{0,-1,"","6","PASSWD"}, {0,-1,"","7","PASSWD"}, \
{0,-1,"","8","PASSWD"}, {0,-1,"","9","PASSWD"}, \
{0,-1,"","10","PASSWD"}, {0,-1,"","11","PASSWD"}, \
{0,-1,"","12","PASSWD"}, {0,-1,"","13","PASSWD"}, \
{0,-1,"","14","PASSWD"}, {0,-1,"","15","PASSWD"}, \
{0,-1,"","16","PASSWD"}, {0,-1,"","17","PASSWD"}, \
{0,-1,"","18","PASSWD"}, {0,-1,"","19","PASSWD"}, \
{0,-1,"","20","PASSWD"}, {0,-1,"","21","PASSWD"}, \
{0,-1,"","22","PASSWD"}, {0,-1,"","23","PASSWD"}, \
{0,-1,"","24","PASSWD"}, {0,-1,"","25","PASSWD"}, \
{0,-1,"","26","PASSWD"}, {0,-1,"","27","PASSWD"}, \
{0,-1,"","28","PASSWD"}, {0,-1,"","29","PASSWD"}, \
{0,-1,"","30","PASSWD"}, {0,-1,"","31","PASSWD"}, \
{0,-1,"","32","PASSWD"}};
// ์ปค๋งจ๋ ๋ผ์ธ์์ ํฌํธ ๋ฒํธ๋ฅผ ์
๋ ฅ๋ฐ์
if (argc != 2) {
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
fputs("IoT Server Start!!\n", stdout);
// ๋ฎคํ
์ค ์ด๊ธฐํ
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';
if (str_len > 0) {
i = 0;
pToken = strtok(idpasswd, "[:]");
while (pToken != NULL) {
pArray[i] = pToken;
if (i++ >= ARR_CNT)
break;
pToken = strtok(NULL, "[:]");
}
for (i = 0; i < MAX_CLNT; i++) {
if (!strcmp(client_info[i].id, pArray[0])) {
if (client_info[i].fd != -1) {
// ์ด๋ฏธ ๋ก๊ทธ์ธ๋ ID์ธ ๊ฒฝ์ฐ
sprintf(msg, "[%s] Already logged!\n", pArray[0]);
write(clnt_sock, msg, strlen(msg));
log_file(msg);
shutdown(clnt_sock, SHUT_WR);
#if 1 // for MCU
shutdown(client_info[i].fd, SHUT_WR);
client_info[i].fd = -1;
#endif
break;
}
if (!strcmp(client_info[i].pw, pArray[1])) {
// ID์ ๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ๋ ๊ฒฝ์ฐ
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;
}
// ํด๋ผ์ด์ธํธ ์ฐ๋ ๋ ํจ์
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};
// ๋ฉ์์ง ์ ๋ณด ๊ตฌ์กฐ์ฒด ๋ฐ ์ฒซ ๋ฒ์งธ ํด๋ผ์ด์ธํธ ์ ๋ณด ์ค์
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);
if (str_len <= 0)
break;
msg[str_len] = '\0';
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);
sprintf(strBuff, "msg : [%s->%s] %s", msg_info.from, msg_info.to, pArray[1]);
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;
}
// ๋ฉ์์ง ์ ์ก ํจ์
void send_msg(MSG_INFO *msg_info, CLIENT_INFO *first_client_info) {
int i = 0;
if (!strcmp(msg_info->to, "ALLMSG")) {
// ๋ชจ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฉ์์ง ์ ์ก
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);
} else if (!strcmp(msg_info->to, "IDLIST")) {
// ๋ชจ๋ ํด๋ผ์ด์ธํธ์ ID ๋ชฉ๋ก์ ์ ์ก
char *idlist = (char *)malloc(ID_SIZE * MAX_CLNT);
msg_info->msg[strlen(msg_info->msg) - 1] = '\0';
strcpy(idlist, msg_info->msg);
for (i = 0; i < MAX_CLNT; i++) {
if ((first_client_info + i)->fd != -1) {
strcat(idlist, (first_client_info + i)->id);
strcat(idlist, " ");
}}
strcat(idlist, "\n");
write(msg_info->fd, idlist, strlen(idlist));
free(idlist);
} else {
// ํน์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฉ์์ง ์ ์ก
for (i = 0; i < MAX_CLNT; i++)
if ((first_client_info + i)->fd != -1)
if (!strcmp(msg_info->to, (first_client_info + i)->id))
write((first_client_info + i)->fd, msg_info->msg, msg_info->len);
}}
// ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ ํจ์
void error_handling(char *msg) {
fputs(msg, stderr);
fputc('\n', stderr);
exit(1);
}
// ๋ก๊ทธ ํ์ผ์ ๋ฉ์์ง ์ถ๋ ฅ ํจ์
void log_file(char *msgstr) {
fputs(msgstr, stdout);
}
make ํ์ผ๋ก ๋น๋
1. make ํ์ผ ์์ฑ
# ์ปดํ์ผ๋ฌ ์ค์
CC := gcc
# ์คํ ํ์ผ ์ด๋ฆ
TARGET_SRV := chat_server
TARGET_CLN := chat_client
# ๋งํฌ ๋ฐ ์ค๋ ๋ฉ ํ๋๊ทธ
LDFLAGS := -D_REENTRANT -pthread
# ์์ค ํ์ผ
SRV_SOURCES := chat_server.c
CLN_SOURCES := chat_client.c
# ๋ชฉ์ ํ์ผ
SRV_OBJECTS := $(SRV_SOURCES:.c=.o)
CLN_OBJECTS := $(CLN_SOURCES:.c=.o)
# ๋ชจ๋ ๋ชฉํ ํ์ผ ๋น๋ ๊ท์น
all: $(TARGET_SRV) $(TARGET_CLN)
# chat_server ์คํ ํ์ผ ๋น๋ ๊ท์น
$(TARGET_SRV): $(SRV_OBJECTS)
$(CC) -o $@ $(SRV_OBJECTS) $(LDFLAGS)
# chat_client ์คํ ํ์ผ ๋น๋ ๊ท์น
$(TARGET_CLN): $(CLN_OBJECTS)
$(CC) -o $@ $(CLN_OBJECTS) $(LDFLAGS)
# ๊ฐ๋ณ ์์ค ํ์ผ์ ๋ชฉ์ ํ์ผ๋ก ์ปดํ์ผ ๊ท์น
%.o: %.c
$(CC) -c -o $@ $<
# ๋ชฉ์ ํ์ผ ๋ฐ ์คํ ํ์ผ ์ ๋ฆฌ ๊ท์น
clean:
rm -f *.o $(TARGET_SRV) $(TARGET_CLN)
# ๋ชจ๋ ํ์ผ, ์คํ ํ์ผ ํฌํจ ์ ๋ฆฌ ๊ท์น
clean_all:
rm -f *.o $(TARGET_SRV) $(TARGET_CLN)
2. ๋น๋ ๊ฒฐ๊ณผ
server, client ๋ชจ๋ ์ฑ๊ณต์ ์ผ๋ก ๋น๋๋จ
server, client ํ๋ก๊ทธ๋จ ์คํ
1. server ์คํ
ํ๋ก๊ทธ๋จ + ํฌํธ ๋ฒํธ๋ฅผ ์ ๋ ฅํ์ฌ ์๋ฒ ํ๋ก๊ทธ๋จ ์คํ
2. client ์คํ
ํ๋ก๊ทธ๋จ + ์๋ฒ ip + ํฌํธ ๋ฒํธ + ๋ฑ๋ก๋ ์์ด๋๋ฅผ ์ ๋ ฅํ์ฌ ํด๋ผ์ด์ธํธ ํ๋ก๊ทธ๋จ ์คํ
๊ฒฐ๊ณผ ํ์ธ
- ๋ฑ๋ก๋ ID๋ก ํด๋ผ์ด์ธํธ ํ๋ก๊ทธ๋จ์ ์คํํ์ฌ ์ฑ๊ณต์ ์ผ๋ก ์๋ฒ์ ์ฐ๊ฒฐ๋๊ณ
์๋ฒ์ ํด๋น ๊ณ์ ์ ์๋จ ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋์์ - ํด๋ผ์ด์ธํธ์์ ์ ์ฒด ์ฑํ ๋ฉ์์ง๋ฅผ ๋ณด๋ธ ๊ฒฐ๊ณผ ์๋ฒ ๋ฐ ์์ ์ ํด๋ผ์ด์ธํธ์ ํด๋น ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋์์
- ํด๋ผ์ด์ธํธ์์ ์ฐ๊ฒฐ์ ์ข ๋ฃ์ ์๋ฒ์์ Disconnect ID : KHJ_LIN + ip ์ฃผ์ ์ถ๋ ฅ๋จ
'embedded' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
MATLAB ์ ๋ฆฌ (0) | 2024.01.08 |
---|---|
[ubuntu] MySQL ํ์ฉ IoT ๋ฐ์ดํฐ ์ ์ด ์ค์ต (0) | 2023.11.23 |
[ubuntu] ์์ผ ํต์ ๋ฐ์ดํฐ ์ ์ก ๋ฐ ์ ์ฅ (0) | 2023.11.20 |
[protocol] bxCAN ์ด๋ก ์ ๋ฆฌ (0) | 2023.10.29 |
[device] CAN Gateway ์ด๋ก ์ ๋ฆฌ (0) | 2023.10.26 |