From 87fff129ebbb98db2ccd0d3d83849874929b6fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=91=E5=B1=91=E5=B1=91?= <1737936302@qq.com> Date: Tue, 14 May 2024 16:45:12 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9bug=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=B8=8D?= =?UTF-8?q?=E6=B4=BB=E8=B7=83=E8=B8=A2=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/main_server.c" | 202 +++++++++++------- .../server/my_Serever.h" | 5 + 2 files changed, 126 insertions(+), 81 deletions(-) diff --git "a/\350\201\212\345\244\251\346\234\215\345\212\241\345\231\250/server/main_server.c" "b/\350\201\212\345\244\251\346\234\215\345\212\241\345\231\250/server/main_server.c" index 01c64a9..4eb8010 100644 --- "a/\350\201\212\345\244\251\346\234\215\345\212\241\345\231\250/server/main_server.c" +++ "b/\350\201\212\345\244\251\346\234\215\345\212\241\345\231\250/server/main_server.c" @@ -1,80 +1,135 @@ #include #include"my_Serever.h" +static void add_in_arr(que_cli * que , fd_set * sets_fd) +{ + for(int i = 0 ; i < MAX_CONNECT ; i++) + { + //只有有效的位置才会被添加 + if(que->exist_curr_fd[i]) + FD_SET(que->connect_fd[i] , sets_fd); + } + //将监听fd添加进来 ,为了在出现链接或者断开连接时不阻塞 + FD_SET(que->listen_fd , sets_fd); +} +static void send_and_recv_mes_process(que_cli * que , char chat_buf[MAX_CONNECT] , int curr) +{ + printf("process chat_buf is %s" , chat_buf); + for(int i = 0 ; i < MAX_CONNECT ; i++) + { + if(que->exist_curr_fd[i] && i != curr) + { + printf("广播%d号文件描述符的消息:%s\n" , que->connect_fd[curr] , chat_buf); + send(que->connect_fd[i] , chat_buf , MAX_BUF , 0); + } + } +} +static void cleaner(que_cli * que , int curr) +{ + printf("%d号文件描述符失效\n" , que->connect_fd[curr]); + pthread_mutex_lock(&(que->_lock)); + que->exist_curr_fd[curr] = false; + que->size_curr--; + close(que->connect_fd[curr]); + que->connect_fd[curr] = -1; + pthread_mutex_unlock(&(que->_lock)); +} +static void send_and_recv(que_cli * que , fd_set * sets_fd) +{ + char chat_buf[MAX_BUF] = {0}; + for(int j = 0 ; j < MAX_CONNECT ; j++) + { + //for(int i = 0 ; i < MAX_CONNECT ; i++)printf("%d is %d ," , que->connect_fd[i] , que->exist_curr_fd[i]); + if(que->exist_curr_fd[j] && FD_ISSET(que->connect_fd[j] , sets_fd)) + { + int count_byte_recv = recv(que->connect_fd[j] , chat_buf , MAX_BUF , 0); + if(count_byte_recv > 0) + { + //printf("cout_byte_recv is %d \n" , count_byte_recv); + send_and_recv_mes_process(que, chat_buf , j); + } + else + { + cleaner(que , j); + } + } + else + { + //不在里面的情况下 + //TODO + } + } +} +static bool over_time(struct timeval * start , struct timeval * end) +{ + long timeuse = 1000000*(end->tv_sec - start->tv_sec) + end->tv_usec-start->tv_usec; + return timeuse/1000000 > MAX_TIME ? true : false; +} +static void judge_over_due(que_cli * que , fd_set * sets_fd) +{ + for(int i = 0 ; i < MAX_CONNECT ; i++) + { + //fd存在的情况下进行判断 + if(que->exist_curr_fd[i]) + { + gettimeofday(&(que->end[i]) , NULL); + //fd存在的情况下如果超时 + if(over_time(&(que->start[i]) , &(que->end[i]))) + { + //只要超时就清理 + char mes[MAX_BUF]; + strcat(mes , "超时断开..\n"); + send(que->connect_fd[i] , mes , MAX_BUF , 0); + cleaner(que , i); + //超时且存在则从sets中删除fd + if(FD_ISSET(que->connect_fd[i] , sets_fd)) + { + //如果这个超时的在fd集合里面就将他删除 + FD_CLR(que->connect_fd[i] , sets_fd); + } + } + else + { + //没超时且存在 + if(FD_ISSET(que->connect_fd[i] , sets_fd)) + { + //更新他的end time + gettimeofday(&(que->start[i]) , NULL); + } + } + } + } +} void * mainbody_chat(void * para) { - //定义聊天缓存 - char chat_buf[2048] = {0}; - - //获取参数 que_cli * que = (que_cli *)para; - - - - //声明待检测集合 fd_set sets_fd; while(1) { + //循环添加模块 //初始化sets FD_ZERO(&sets_fd); - - - //准备上锁 pthread_mutex_lock(&(que->_lock)); if(que->size_curr == 0) { pthread_cond_wait(&(que->cond) , &(que->_lock)); } - //将que里面所有的connect_fd进行扫描 , 进行添加 - for(int i = 0 ; i < MAX_CONNECT ; i++) - { - //只有有效的位置才会被添加 - if(que->exist_curr_fd[i]) - FD_SET(que->connect_fd[i] , &sets_fd); - } - //将监听fd添加进来 ,为了在出现链接或者断开连接时不阻塞 - FD_SET(que->listen_fd , &sets_fd); + add_in_arr(que , &sets_fd); pthread_mutex_unlock(&(que->_lock)); +/**************************赋值模块**************************************/ - //阻塞检测 - select(MAX_CONNECT + 1 , &sets_fd , NULL , NULL , NULL); - - for(int j = 0 ; j < MAX_CONNECT ; j++) - { - if(FD_ISSET(que->connect_fd[j] , &sets_fd)) - { - int count_byte_recv = recv(que->connect_fd[j] , chat_buf , 2048 , 0); - - //count_byte_recv是接收到的有效字节数量 , 大于 0 是正常的 , 小于等于 0 代表链接挂了 - //链接挂了 将其对应有效位置设置为false - if(count_byte_recv > 0) - { - //将消息发送给其余的客户端 - printf("来自fd : %d ,内容大小是:%d , 内容是 %s\n" , que->connect_fd[j] , count_byte_recv , chat_buf); - for(int i = 0 ; i < MAX_CONNECT ; i++) - { - if(que->exist_curr_fd[i] && i != j) - { - printf("发%d的数据给%d , 内容是:%s\n" , que->connect_fd[j] , que->connect_fd[i] , chat_buf); - send(que->connect_fd[i] , chat_buf , strlen(chat_buf) , 0); - } - } - - memset(chat_buf , 0 , sizeof(chat_buf)); - } - else - { - printf("%d号文件描述符失效\n" ,que->connect_fd[j]); - //标记为失效,并且close文件描述符号 - que->exist_curr_fd[j] = false; - que->size_curr--; - close(que->connect_fd[j]); - } - } + //循环阻塞检测 + select(MAX_CONNECT + 3 , &sets_fd , NULL , NULL , NULL); +/*****************************中间模块**************************************/ - } + //循环检查有没有超时 + judge_over_due(que , &sets_fd); + //循环处理消息 + send_and_recv(que , &sets_fd); + printf("send and recv is ending\n"); +/*******************************处理模块****************************************/ } } @@ -83,26 +138,19 @@ void * mainbody_chat(void * para) static void init_que(que_cli * que , int listen_fd) { //当前连接数为 0 - que->size_curr = 0; - memset(que->exist_curr_fd , 0 , MAX_CONNECT); - memset(que->connect_fd , -1 , MAX_CONNECT); - pthread_mutex_init(&(que->_lock) , NULL); - pthread_cond_init(&(que->cond) , NULL); - //同步信号量的初始化 que->syn_flag = 0; - - que->listen_fd = listen_fd; + memset(que->start , 0 , MAX_CONNECT); + memset(que->end , 0 , MAX_CONNECT); } int main(int argc, char *argv[]) { - SockAddr4 sa4; Addr4 ad4; argument arg; @@ -116,9 +164,7 @@ int main(int argc, char *argv[]) arg.ad4 = &ad4; arg.max_connect = 10; - server_can can = get_server_can(arg); - //printf("%d\n",sa4.sin_addr.s_addr); //共享变量 que_cli qc; @@ -127,14 +173,9 @@ int main(int argc, char *argv[]) //初始化 int connect_fd = -1; pthread_t muti_person_chat_pthread; - pthread_create( - &muti_person_chat_pthread , - NULL , - mainbody_chat , - (void *)&qc - ); + pthread_create(&muti_person_chat_pthread , NULL , mainbody_chat , (void *)&qc); - char mes[64] = {0}; + char mes[MAX_BUF] = {0}; while(1) { //阻塞等待 @@ -143,7 +184,6 @@ int main(int argc, char *argv[]) if(connect_fd > 0) { int i = 0; - strcat(mes , "正在链接..."); send(connect_fd , mes , strlen(mes) , 0); memset(mes , 0 , sizeof(mes)); @@ -156,11 +196,9 @@ int main(int argc, char *argv[]) { qc.connect_fd[i] = connect_fd; qc.size_curr++; - - //表明被此位置connnect_fd是有效的 qc.exist_curr_fd[i] = true; - - //找到一个位置后立刻退出此次循环 + gettimeofday(&(qc.start[i]) , NULL); + gettimeofday(&(qc.end[i]) , NULL); break; } } @@ -182,12 +220,14 @@ int main(int argc, char *argv[]) { //accept错误情况 //TODO - } + + printf("有效位 :"); for(int i = 0 ; i < MAX_CONNECT ; i++) { - printf("%d 号是 :%d\n" , i , qc.exist_curr_fd[i]); + printf("%d" , qc.exist_curr_fd[i]); } + printf("\n"); } return 0; } diff --git "a/\350\201\212\345\244\251\346\234\215\345\212\241\345\231\250/server/my_Serever.h" "b/\350\201\212\345\244\251\346\234\215\345\212\241\345\231\250/server/my_Serever.h" index 1b39a26..92c0985 100644 --- "a/\350\201\212\345\244\251\346\234\215\345\212\241\345\231\250/server/my_Serever.h" +++ "b/\350\201\212\345\244\251\346\234\215\345\212\241\345\231\250/server/my_Serever.h" @@ -1,5 +1,7 @@ #include #define MAX_CONNECT 10 +#define MAX_BUF 2048 +#define MAX_TIME 10 typedef struct socket_all_para { char ip[15]; @@ -58,6 +60,9 @@ typedef struct client_queue //监听fd int listen_fd; + + struct timeval start[MAX_CONNECT]; + struct timeval end[MAX_CONNECT]; }que_cli; -- Gitee