int my_public(int confd, struct chat *tran_msg) { int n_read; int n_write; struct user_link *temp_user = NULL; struct user_link *temp_online = NULL; temp_user = find_online(tran_msg->m_name); /*判断是否被禁言*/ if (temp_user->speak_flag == 0) { strcpy(tran_msg->m_name, "Server\n"); strcpy(tran_msg->msg, "Sorry ,you can't speak! Plead conect to administrator!"); n_write = Write(confd, tran_msg, sizeof(struct chat)); /*发送到指定的聊天对象*/ if (n_write <= 0) { fputs("private : 读取错误\n", stderr); temp_online = find_by_confd(confd); delete_online(temp_online); notice(temp_online->user_msg.name, OFFLINE); close(confd); return -1; } return 0; } debug_msg("my_public:tran_msg->msg: %s\n", tran_msg->msg); //send to ever user for(temp_user = online_head;temp_user != NULL; temp_user = temp_user->next) { n_write = Write(temp_user->confd,tran_msg,sizeof(struct chat)); if(n_write <= 0) { fputs("public: 写入错误\n",stderr); temp_online = find_by_confd(temp_user->confd); delete_online(temp_online); notice(temp_online->user_msg.name,OFFLINE); close(temp_user->confd); } debug_msg("my_public:temp_user->confd %d\n",temp_user->confd); } return 0; }
int scan_online(int confd) { struct user_link *temp_online = NULL; struct user_link *temp = NULL; struct chat tran_msg; memset(&tran_msg,0,sizeof(tran_msg)); int n_write; int debug_flag = 0; strcpy(tran_msg.m_name,"Server\n"); strcpy(tran_msg.msg,"Begin to browser the online user\n"); n_write = Write(confd,&tran_msg,sizeof(tran_msg)); if(n_write <= 0) { temp_online = find_by_confd(confd); delete_online(temp_online); fputs("scan_online: 读取错误\n",stderr); notice(temp_online->user_msg.name,OFFLINE); close(confd); return -1; } memset(&tran_msg,0,sizeof(tran_msg)); /*循环将在线用户发送给需要查看在线用户的客户*/ for (temp = online_head; temp != NULL; temp = temp->next) { /*将在线用户的名字存进需要传送的缓存区*/ strcpy(tran_msg.m_name, "Server\n"); strcpy(tran_msg.msg, temp->user_msg.name); /*将用户姓名写入到通信端口*/ n_write = Write(confd, &tran_msg, sizeof(tran_msg)); if (n_write <= 0) { temp_online = find_by_confd(confd); delete_online(temp_online); notice(temp_online->user_msg.name, OFFLINE); fputs("scan_online:读取错误\n", stderr); close(confd); return -1; } debug_msg("debug_flag = %d\n", debug_flag++); memset(&tran_msg, 0, sizeof(tran_msg)); } strcpy(tran_msg.m_name, "Server\n"); strcpy(tran_msg.msg, "Browser the online user over\n"); /*将用户姓名写入到通信端口*/ n_write = Write(confd, &tran_msg, sizeof(tran_msg)); if (n_write <= 0) { close(confd); temp_online = find_by_confd(confd); delete_online(temp_online); notice(temp_online->user_msg.name, OFFLINE); fputs("scan_online:读取错误\n", stderr); return -1; } return 0; }
int manage_chat(int confd) { struct chat tran_msg; memset(&tran_msg,0,sizeof(tran_msg)); int n_read; int n_write; struct user_link *temp_online = NULL; while(1) { n_read = Read(confd, &tran_msg,sizeof(tran_msg)); if(n_read <= 0) { fputs("manage_chat: Read failure\n",stderr); temp_online = find_by_confd(confd); debug_msg("manage_chat: m_name %s", temp_online->user_msg.name ); delete_online(temp_online); notice(temp_online->user_msg.name,OFFLINE); // notice OFFLINE close(confd); return -1; } /*analyse user's requierments*/ debug_msg("manage_chat:n_read = %d, buf[0] = %c\n",n_read,tran_msg.mode[0]); switch(tran_msg.mode[0]) { case PRIVATE: { my_private(confd,&tran_msg); break; } case PUBLIC: { my_public(confd,&tran_msg); break; } case QUIT_CHAT: //log out { struct user_link *temp_link = find_online(tran_msg.m_name); debug_msg("要删除的名字:%s", temp_link->user_msg.name); debug_msg("要删除的通信端口号:%d\n", temp_link->confd); pthread_mutex_lock(&log_lock); delete_online(temp_link); notice(temp_link->user_msg.name,OFFLINE); pthread_mutex_unlock(&log_lock); debug_msg("查看删除后的在线用户链表\n"); traverse(online_head); debug_msg("查看删除后的在线用户链表完毕\n:"); strcpy(tran_msg.m_name,"Sever\n"); strcpy(tran_msg.msg,"您已经成功退出聊天模式\n"); n_write = Write(confd,&tran_msg,sizeof(tran_msg)); if(n_write <= 0) { temp_online = find_by_confd(confd); delete_online(temp_online); close(confd); notice(temp_online->user_msg.name,OFFLINE); fputs("服务器读取错误\n",stderr); return -1; } return 0; } case SCAN_ONLINE: { scan_online(confd); debug_msg("scanf_online: %s", tran_msg.mode); break; } case KICK_ALL: //super root { struct user_link *temp = NULL; notice_close_serv(confd); sleep(10); strcpy(tran_msg.m_name, "Server\n"); strcpy(tran_msg.msg,"Sever has been closed, you are forced to log out\n"); for(temp = online_head; temp != NULL; temp=temp->next) { n_write = Write(temp->confd,&tran_msg, sizeof(tran_msg)); if(n_write <= 0) { fputs("The user is not online\n",stderr); temp_online = find_by_confd(temp->confd); delete_online(temp_online); notice(temp_online->user_msg.name,OFFLINE); close(confd); return -1; } temp_online = find_by_confd(temp->confd); delete_online(temp_online); } exit(0); } case MANAGE_SPEAK: { debug_msg("Man-sp:进入服务\n"); debug_msg("Man-sp:f_name :%s confd:%d\n", tran_msg.f_name, confd); manage_speak(&tran_msg, confd); break; } case KICK_ONE: { debug_msg("kick one\n"); kick_one(&tran_msg,confd); break; } default: { strcpy(tran_msg.msg,"您输入的选项有误\n"); n_write = Write(confd, &tran_msg, sizeof(tran_msg)); /*写回给客户端*/ if (n_write <= 0) { temp_online = find_by_confd(confd); delete_online(temp_online); notice(temp_online->user_msg.name, OFFLINE); close(confd); fputs("服务器读取错误\n", stderr); return -1; } break; } } memset(&tran_msg,0,sizeof(tran_msg)); } }
int my_private(int confd, struct chat *temp) { debug_msg("private: confd = %d\n",confd); struct user_link *temp_user = NULL; int n_read; int n_write; int temp_confd; struct user_link *temp_online = NULL; debug_msg("private NAME = %s", temp->f_name); debug_msg("private NAME = %s", temp->m_name); temp_user = find_online(temp->m_name); //judge if can speak if(temp_user->speak_flag == 0) { strcpy(temp->m_name,"Sever\n"); strcpy(temp->msg,"Sorry,you can't speak,plead contact administrator!"); n_write = Write(confd,temp,sizeof(struct chat)); if(n_write <= 0) { fputs("private : 读取错误\n",stderr); temp_online = find_by_confd(confd); delete_online(temp_online); notice(temp_online->user_msg.name,OFFLINE); close(confd); return -1; } return 0; } //judge if the other one is online? temp_user = find_online(temp->f_name); if(temp_user == NULL) //offline { strcpy(temp->m_name,"Server\n"); strcpy(temp->msg, "The people you want to talk is offline\n"); n_write = Write(confd,temp,sizeof(struct chat)); //feedback to client if(n_write <= 0) { fputs("private: 读取错误\n",stderr); temp_online = find_by_confd(confd); delete_online(temp_online); notice(temp_online->user_msg.name,OFFLINE); close(confd); return -1; } return 0; } //begin connection debug_msg("private: name = %s",temp->f_name); temp_confd = temp_user->confd; debug_msg("private: confd = %d",temp_confd); debug_msg("开始通信\n"); n_write = Write(temp_confd,temp,sizeof(struct chat)); // to the other client if(n_write <= 0) { fputs("private: Write failure\n",stderr); temp_online = find_by_confd(temp_confd); delete_online(temp_online); notice(temp_online->user_msg.name,OFFLINE); close(temp_confd); return -1; return -1; } debug_msg("结束通信\n"); return 0; }
void read_message(void *arg) { int fd = *((int *)arg); int to_fd; int count; int result; int temp; struct message msg; struct online *p; struct online *q; struct online *m; while(1) { if((count = read(fd,&msg,sizeof(msg))) != 0) //读取客户端传来的信息 { //printf("aaaaaaaaaaaaa%d\n",msg.action); if(msg.action == log) { p = (struct online*)malloc(sizeof(struct online)); p->fd = fd; p->ID = msg.ID; strcpy(p->passwd,msg.passwd); if(find_id(msg.ID) == 0) //找到已经登录的ID号,返回have_log,防止重复登录 { msg.action = have_log; write(fd,&msg,sizeof(msg)); } else { result = server_log(p); //去数据库中核实登录信息和注册信息是否一致 //printf("bbbbbbbbbbbbb%d\n",result); strcpy(msg.name,p->name); if(result == log_ok) { msg.action = log_ok; insert_online(p); //登录成功后,插入链表,用来显示在线的用户 write(fd,&msg,sizeof(msg)); sleep(8); read_unlog_msg(msg.name,fd); //读保存在服务器里的离线消息 } if(result == admin_log_ok) { msg.action = admin_log_ok; insert_online(p); write(fd,&msg,sizeof(msg)); sleep(8); read_unlog_msg(msg.name,fd); } if(result == passwd_error) { msg.action = passwd_error; write(fd,&msg,sizeof(msg)); } if(result == ID_error) { msg.action = ID_error; write(fd,&msg,sizeof(msg)); } } } if(msg.action == reg) { p = (struct online*)malloc(sizeof(struct online)); //给结构体p分配空间 p->fd = fd; //为写入数据库作准备 strcpy(p->name,msg.name); strcpy(p->passwd,msg.passwd); //result = insert_online(p); //if(result == insert_ok) srand(time(0)); //防止随机数重复 temp = rand(); //生成随机数 p->ID = temp; msg.ID = p->ID; //返回给客户端的ID和reg_ok msg.action = reg_ok; //通知客户端“注册成功”的标志 my_sqlite(p); //注册时的信息写入数据库 write(fd,&msg,sizeof(msg));//把生成的id号传给客户端 } if(msg.action == say) { if(find_ban(fd) == ban) { msg.action = ban; write(fd,&msg,sizeof(msg)); msg.action = -2; //防止和谁聊天,谁被禁言 } else { to_fd = find_fd(msg.toname);//聊天通过寻找对方的fd,找不到返回-1,找到返回对方的fd if(to_fd == -1) { msg.action = to_fd; reserve_unlog_msg(&msg); reserve_chat_msg(&msg); write(fd,&msg,sizeof(msg));//没找到客户2,就返回客户1的fd } else { reserve_chat_msg(&msg); write(to_fd,&msg,sizeof(msg));//找到了客户2,就返回客户2的fd } } } if(msg.action == say_all) { if(find_ban(fd) == ban) { msg.action = ban; write(fd,&msg,sizeof(msg)); msg.action = -2; } else { struct online *temp = head; //遍历链表,传送每一个fd reserve_chat_msg(&msg); while(temp != NULL) { write(temp->fd,&msg,sizeof(msg)); temp = temp->next; } } } if(msg.action == send_face) { if(find_ban(fd) == ban) { msg.action = ban; write(fd,&msg,sizeof(msg)); msg.action = -2; //防止和谁聊天,谁被禁言 } else { to_fd = find_fd(msg.toname); if(to_fd == -1) { msg.action = to_fd; write(fd,&msg,sizeof(msg)); } else { write(to_fd,&msg,sizeof(msg)); } } } if(msg.action == change) { struct online *temp = head; //通过查找ID,替换昵称和密码 q = (struct online*)malloc(sizeof(struct online)); while(temp->fd == fd) { q->ID = msg.ID; strcpy(q->passwd,msg.passwd); strcpy(q->name,msg.name); //printf("aaaaaaaaaa%ldaaaaaaa%saaaaaaa%s\n",q->ID,q->passwd,q->name); result = server_change(q); //printf("cccccccccccccccckui zi shi sha bi!\n"); if(result == change_ok) { msg.action = change_ok; write(fd,&msg,sizeof(msg)); break; } else { msg.action = change_error; write(fd,&msg,sizeof(msg)); break; } temp = temp->next; } } if(msg.action == show) { struct online *temp = head; //遍历链表,传送每一个fd while(temp != NULL) { msg.ID = temp->ID; //错误:这两句话要加,不然信息是同一个人的 my_strcpy(msg.name,temp->name); write(fd,&msg,sizeof(msg)); //错误:这里是fd,是在发过来的客户的界面显示 temp = temp->next; } } if(msg.action == quit) { //printf("aaaaaaaaaaaaa%ld\n",msg.ID); m = (struct online*)malloc(sizeof(struct online)); m->fd = fd; //m->ID = msg.ID; //my_strcpy(m->passwd,msg.passwd); //my_strcpy(m->name,msg.name); //printf("aaaaaaaaaaaaa%ld\n",msg.ID); delete_online(m); //链表中不显示该用户 msg.action = quit_ok; write(fd,&msg,sizeof(msg)); /* if(result == delete_error) { msg.action = quit_error; write(fd,&msg,sizeof(msg)); } */ } if(msg.action == kick) { to_fd = find_fd(msg.toname); //fd = find_fd(msg.name); if(to_fd == -1 || my_strcmp(msg.name,msg.toname) == 0) { msg.action = -1; write(fd,&msg,sizeof(msg)); } else { m = (struct online*)malloc(sizeof(struct online)); m->fd = to_fd; delete_online(m); //链表中不显示该用户 msg.action = kick_ok; write(fd,&msg,sizeof(msg)); write(to_fd,&msg,sizeof(msg)); } } if(msg.action == ban) { //printf("nnnnnnn%s\n",msg.toname); to_fd = find_fd(msg.toname); struct online *temp; struct online *str = head; temp = (struct online*)malloc(sizeof(struct online)); while(str != NULL) { msg.action = ban_tell_all; //不能写在后面,找到了就要发过去 write(str->fd,&msg,sizeof(msg)); if(str->fd == to_fd) { temp->fd = to_fd; temp->ID = str->ID; my_strcpy(temp->name,str->name); //insert_online(temp); 错误:不能插入head中,那是显示在线链表的 insert_ban(temp); //建立一个禁言链表 } str = str->next; } } if(msg.action == solve_ban) { to_fd = find_fd(msg.toname); if((find_ban(to_fd)) == -1) { //printf("aaaaaaaaaaaaaaaaaa\n"); msg.action = solve_error; write(fd,&msg,sizeof(msg)); //printf("aaaaaaaaaaaaaaaaaa\n"); } else { m = (struct online*)malloc(sizeof(struct online)); m->fd = to_fd; delete_ban(m); //删除禁言链表中该用户名字 msg.action = solve_ban; struct online *temp = head; while(temp != NULL) //通知所有人,该用户被解禁了 { write(temp->fd,&msg,sizeof(msg)); temp = temp->next; } } } if(msg.action == see_record) { //printf("cccccccccccccccccccccccccc\n"); read_chat_msg(msg.name,fd); write(fd,&msg,sizeof(msg)); } } else //客户端ctrl+c之后,将在线的用户删除掉,show的时候少掉这个异常退出的用户 { struct online *m = (struct online*)malloc(sizeof(struct online)); m->fd = fd; delete_online(m); } } }