暑假项目聊天室(0)--源码

引言

暑假留校结束了,暑假中最重要的一个项目聊天室,在最终的努力下还是完成了,下面就来分析一下我写的聊天室;


文件

  • main.c 服务端主函数
  • main_cli.c 客户端主函数和客户端收发线程函数
  • my_deal.h my_deal.c 服务端线程函数服务端菜单函数
  • my_err.h my_err.c 错误处理函数
  • my_friends.h my_friends.c 处理好友的函数
  • my_group.h my_group.c 处理群的函数
  • my_login.h my_login.c 登录注册函数
  • my_mune.h my_mune.c 服务端菜单
  • my_mysql.h my_mysql.c 数据库函数
  • my_pack.h my_pack.c 数据结构的集合
  • my_socket.h my_socket.c 服务端与客户端连接
  • my_talk.h my_talk.c 聊天,群聊,发文件
  • user_number.txt group_number.txt 负责分配群号账号

源码

main.c

#include <mysql/mysql.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/epoll.h>
#include <pthread.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#include "my_friends.h"
#include "my_deal.h"
#include "my_mysql.h"
#include "my_socket.h"
#include "my_err.h"
#include "my_pack.h"

#define MAXEPOLL 1024


int main() {
	 int                        i;
	 int                        sock_fd;
	 int                        conn_fd;
	 int                        socklen;
	 int                        acceptcont = 0;
	 int                        kdpfd;
	 int                        curfds;
	 int                        nfds;
	 char                       need[MAXIN];
	 MYSQL                      mysql;
	 struct sockaddr_in         cli;
	 struct epoll_event         ev;
	 struct epoll_event         events[MAXEPOLL];
	 PACK                       recv_pack;
	 PACK                       *pack;
	 pthread_t                  pid;
     MYSQL_RES                  *result;
    
     pthread_mutex_init(&mutex, NULL);
	 socklen = sizeof(struct sockaddr_in);
	 mysql = accept_mysql();
	 sock_fd = my_accept_seve();

	 kdpfd = epoll_create(MAXEPOLL);

	 ev.events = EPOLLIN | EPOLLET;
	 ev.data.fd = sock_fd;

	 if(epoll_ctl(kdpfd, EPOLL_CTL_ADD, sock_fd, &ev) < 0) {
	 	my_err("epoll_ctl", __LINE__);
	 }

	 curfds = 1;

	while(1) {
	 	if((nfds = epoll_wait(kdpfd, events, curfds, -1)) < 0){
	 		my_err("epoll_wait", __LINE__);
	 }

 	for (i = 0; i < nfds; i++) { 
		if (events[i].data.fd == sock_fd) {
 			if ((conn_fd = accept(sock_fd, (struct sockaddr*)&cli, &socklen)) < 0) {
 				my_err("accept", __LINE__);
 			}
 			printf("连接成功,套接字编号%d\n", conn_fd);
 			acceptcont++;

 			ev.events = EPOLLIN | EPOLLET;
 			ev.data.fd = conn_fd;

 			if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, conn_fd, &ev) < 0) {
 				my_err("epoll_ctl", __LINE__);
 			}
 			curfds++;
 			continue;
 		} else if (events[i].events & EPOLLIN) { 
			memset(&recv_pack, 0, sizeof(PACK));
 			if (recv(events[i].data.fd, &recv_pack, sizeof(PACK), MSG_WAITALL) < 0) {
 				close(events[i].data.fd);
 				perror("recv");
 				continue;
 			}
            if (recv_pack.type == EXIT) {
                if (send(events[i].data.fd, &recv_pack, sizeof(PACK), 0) < 0) {
                    my_err("send", __LINE__);
                }
                memset(need, 0, sizeof(need));
                sprintf(need, "update user_data set user_state = 0 where user_state = 1 and user_socket = %d", events[i].data.fd);
                mysql_query(&mysql, need);
                epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[i].data.fd, &ev);
                curfds--;
                
                continue;
            }
			if (recv_pack.type == LOGIN) {
 		    	memset(need, 0, sizeof(need));
                sprintf(need, "select *from user_data where account = %d", recv_pack.data.send_account);
                pthread_mutex_lock(&mutex);
                mysql_query(&mysql, need);
                result = mysql_store_result(&mysql);
                if (!mysql_fetch_row(result)) {
                    recv_pack.type = ACCOUNT_ERROR;
                    memset(recv_pack.data.write_buff, 0, sizeof(recv_pack.data.write_buff));
                    printf("$$sad\n");
                    strcpy(recv_pack.data.write_buff, "password error");
                    if (send(events[i].data.fd, &recv_pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                    pthread_mutex_unlock(&mutex);
                    continue;
                }
 		    	memset(need, 0, sizeof(need)); 
 		    	sprintf(need, "update user_data set user_socket = %d where account = %d", events[i].data.fd, recv_pack.data.send_account);
 	    		mysql_query(&mysql, need); 
                pthread_mutex_unlock(&mutex);
            }
            recv_pack.data.recv_fd = events[i].data.fd;
 			pack = (PACK*)malloc(sizeof(PACK));
 			memcpy(pack, &recv_pack, sizeof(PACK));
 			pthread_create(&pid, NULL, deal, (void*)pack);
            }
         }
    } 
}

mian_cli.c

#include <stdio.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <termios.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

#include "my_pack.h"
#include "my_socket.h"
#include "my_err.h"
#include "my_mune.h"

PACK *send_pack;
PACK *recv_pack;
BOX *box;
FRIEND *list;
MESSAGE *message;
GROUP_MESSAGE *group_message;
GROUP *member_list;
GROUP_G *group_list;
FLE *file;
int sing;

/* 用来发送数据的线程 */
void *thread_read(void *sock_fd) {
    int               choose;
    char              password[20];
    char              ch;
    int               i = 0;
    struct termios    old, new;
    
    tcgetattr(0, &old);
    new = old;
    new.c_lflag &= ~(ECHO | ICANON);
    send_pack = (PACK *)malloc(sizeof(PACK));
    /* 1为登录,2为注册,3为退出 */
    while (1) {
        login_mune();
        printf("请选择你需要的功能:\n");
        scanf("%d", &choose);
        switch (choose) {
            case 1:
                   {
                       send_pack->type = LOGIN;
                       printf("请输入账号:\n");
                       scanf("%d", &send_pack->data.send_account);
                       getchar();
                       printf("请输入密码:\n");
                       i = 0;
                       while (1) {
                           tcsetattr(0, TCSANOW, &new);
                           scanf("%c", &ch);
                           tcsetattr(0, TCSANOW, &old);
                           if (ch == '\n') {
                               send_pack->data.read_buff[i] = '\0';
                               break;
                           }
                           send_pack->data.read_buff[i++] = ch;
                           printf("*");
                       }
                       printf("\n");
                      // scanf("%s", send_pack->data.read_buff);
                       memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                       if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                           my_err("send", __LINE__);
                       }
                       pthread_mutex_lock(&mutex_cli);
                       while (sing == 0) {
                            pthread_cond_wait(&cond_cli, &mutex_cli);
                       }
                       pthread_mutex_unlock(&mutex_cli);
                       printf("%s\n", send_pack->data.write_buff);
                       sing = 0;
                       break;
                   }
           case 2:
                   {
                       send_pack->type = REGISTERED;
                       printf("请输入昵称:\n");
                       scanf("%s", send_pack->data.send_user);
                       getchar();
                       printf("请输入密码:\n");
                       i = 0;
                       while (1) {
                           tcsetattr(0, TCSANOW, &new);
                           scanf("%c", &ch);
                           tcsetattr(0, TCSANOW, &old);
                           if (ch == '\n') {
                               send_pack->data.read_buff[i] = '\0';
                               break;
                           }
                           send_pack->data.read_buff[i++] = ch;
                           printf("*");
                       }
                       printf("\n");
                    // scanf("%s", send_pack->data.read_buff);
                       i = 0;
                       printf("请再次输入密码:\n");
                       while (1) {
                           tcsetattr(0, TCSANOW, &new);
                           scanf("%c", &ch);
                           tcsetattr(0, TCSANOW, &old);
                           if (ch == '\n') {
                               password[i] = '\0';
                               break;
                           }
                           password[i++] = ch;
                           printf("*"); 
                       }
                       printf("\n");
                      // scanf("%s", password);
                       if (strcmp(password, send_pack->data.read_buff) == 0) {
                           printf("两次输入一制OK\n");
                           if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                               my_err("send", __LINE__);
                           }
                           pthread_mutex_lock(&mutex_cli);
                           pthread_cond_wait(&cond_cli, &mutex_cli);
                           pthread_mutex_unlock(&mutex_cli);
                       } else {
                           printf("两次密码不一致!!!\n") ;
                           printf("按下回车继续.......");
                           choose = 5;
                           getchar();
                       }
                       break;
                   }
           case 3:
                   {
                       send_pack->type = FIND_PASSWORD;
                       printf("请输入你的账号:\n");
                       scanf("%d", &send_pack->data.send_account);
                       getchar();
                       printf("请输入你的好友数量:\n");
                       scanf("%d", &send_pack->data.recv_account);
                       getchar();
                       if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                           my_err("send", __LINE__);
                       }
                       pthread_mutex_lock(&mutex_cli);
                       pthread_cond_wait(&cond_cli, &mutex_cli);
                       pthread_mutex_unlock(&mutex_cli);
                       printf("%s\n", send_pack->data.write_buff);
                       printf("按下回车键继续.......");
                       getchar();
                       break;
                   }
           case 4:
                   {
                       send_pack->type = EXIT;
                       if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                           my_err("send", __LINE__);
                       }
                       pthread_exit(0);
                   }
           default:
                   {
                       printf("狗东西,好好输入!!!\n");
                       printf("输入回车继续......");
                       getchar();
                       getchar();
                       break;
                   }
        }
        if (choose > 4 || choose < 1) {
            continue;   
        } else if (choose == 1) {
            if (strcmp(send_pack->data.write_buff, "password error") == 0) {
                printf("密码错误或账号错误!!\n按下回车继续.....");
                getchar();
                continue;
            } else {
                printf("登陆成功!!\n");
                printf("按下回车继续......\n");
                getchar();
                break;
            }
        } else if (choose == 2) {
            printf("注册成功!!\n");
            printf("您的账号为:%d\n", send_pack->data.send_account);
            printf("按下回车继续.......");
            getchar();
            continue;
        } else if (choose == 3) {
            continue;
        }
    }
    while (1) {
        mune();
        printf("\n");
        scanf("%d", &choose);
        getchar();
        switch(choose) {
            case 1:
                    {
                        send_pack->type = CHANGE_PASSWORD;
                        printf("请输入原始密码:\n");
                        i = 0;
                        while (1) {
                            tcsetattr(0, TCSANOW, &new);
                            scanf("%c", &ch);
                            tcsetattr(0, TCSANOW, &old);
                            if (ch == '\n') {
                                send_pack->data.read_buff[i] = '\0';
                                break;
                            }
                            send_pack->data.read_buff[i++] = ch;
                            printf("*");
                        }
                        printf("\n");
                        // scanf("%s", send_pack->data.read_buff);
                        printf("请输入修改后的密码:\n");
                        i = 0;
                        while (1) {
                            tcsetattr(0, TCSANOW, &new);
                            scanf("%c", &ch);
                            tcsetattr(0, TCSANOW, &old);
                            if (ch == '\n') {
                                send_pack->data.write_buff[i] = '\0';
                                break;
                            }
                            send_pack->data.write_buff[i++] = ch;
                            printf("*");
                        }
                        printf("\n");
                        // scanf("%s", send_pack->data.write_buff);
                         int ret;
                        if ((ret = send(*(int *)sock_fd, send_pack, sizeof(PACK), 0)) < 0) {
                            my_err("send", __LINE__);
                        }
                        printf("^^%d\n", ret);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        printf("%s\n", recv_pack->data.write_buff);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("修改成功!!!\n");
                            printf("按下回车继续......\n");
                            getchar();
                        } else {
                            printf("修改失败!!!\n");
                            printf("按下回车继续.......\n");
                            getchar();
                        }
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        break;
                    }
            case 2:
                    {
                        send_pack->type = ADD_FRIEND;
                        printf("请输入你想添加好友的账号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("发送成功等待对方确认!!\n");
                            printf("按下回车键继续.......");
                            getchar();
                        } else {
                            printf("对方已经是你的好友或者对方不存在!!!\n");
                            printf("按下回车键继续.......");
                            getchar();
                        }
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        break;
                    }
            case 3:
                    {
                        send_pack->type = DEL_FRIEND;
                        printf("请输入想要删除好友的账号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("删除成功!!!\n");
                            printf("按下回车键继续..........");
                            getchar();
                        } else {
                            printf("你没有账号为%d的好友!!!\n", send_pack->data.recv_account);
                            printf("按下回车继续........");
                            getchar();
                        }
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        break;
                    }
            case 4:
                    {
                        pthread_mutex_lock(&mutex_cli);
                        send_pack->type = FRIENDS_PLZ;
                        if (box->friend_number == 0) {
                            printf("消息盒子里没有好友请求!!\n");
                            printf("输入回车继续......");
                            pthread_mutex_unlock(&mutex);
                            getchar();
                        } else {
                            for (int i = 0; i < box->friend_number; ++i) {
                                printf("%s\n", box->write_buff[i]);
                                send_pack->data.recv_account = box->plz_account[i];
                                printf("请选择: 1. 接受 2. 拒绝 3. 忽略\n");
                                scanf("%d", &choose);
                                getchar();
                                if (choose == 3) {
                                    continue;
                                } else if (choose == 1) {
                                    strcpy(send_pack->data.read_buff, "agree");
                                    if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                                        my_err("send", __LINE__);
                                    }
                                } else if (choose == 2) {
                                    strcpy(send_pack->data.read_buff, "disagree");
                                    if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                                        my_err("send", __LINE__);
                                    }
                                }
                            }
                            box->friend_number = 0;
                            printf("处理完毕!!\n");
                            printf("回车键继续.......");
                            pthread_mutex_unlock(&mutex_cli);
                            memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                            memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.read_buff));
                            getchar();
                        }
                        break;
                    }
            case 5:
                    {
                        send_pack->type = BLACK_FRIEND;
                        printf("请输入你想要拉黑的好友:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("账号为%d的好友已经被拉黑!!!\n", send_pack->data.recv_account);
                            printf("按下回车继续.......");
                            getchar();
                        } else {
                            printf("对方不是你的好友或对方不存在!!!\n");
                            printf("按下回车继续...........");
                            getchar();
                        }
                        break;
                    }
            case 6:
                    {
                        send_pack->type = WHITE_FRIEND;
                        printf("请输入你想从黑名单里去除的好友:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("账号为%d的好友从黑名单里剔除!!\n", send_pack->data.recv_account);
                            printf("按下回车继续......");
                            getchar();
                        } else {
                            printf("你没有这个好友或者这个好友不在黑名单!!\n");
                            printf("按下回车键继续.......");
                            getchar();
                        }
                        break;
                    }
            case 7:
                    {
                        send_pack->type = CARE_FRIEND;
                        printf("请输入你想要加入特别关心的好友账号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("账号为%d的好友加入特别关心\n", send_pack->data.recv_account);
                            printf("按下回车继续......");
                            getchar();
                        } else {
                            printf("你没有这个好友!!\n");
                            printf("按下回车键继续.......");
                            getchar();
                        }
                        break;
                    }
            case 8:
                    {
                        send_pack->type = DISCARE_FRIEND;
                        printf("请输入你想要取关的好友账号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("账号为%d的好友取消特别关心\n", send_pack->data.recv_account);
                            printf("按下回车继续......");
                            getchar();
                        } else {
                            printf("你没有这个好友!!\n");
                            printf("按下回车键继续.......");
                            getchar();
                        }
                        break;
                    }
            case 9:
                    {
                        send_pack->type = LOOK_LIST;
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        printf("%s\n", send_pack->data.write_buff);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("好友列表:\n");
                            for (int i = 0; i < list->friend_number; i++) {
                                printf("%d\t%-20s\t", list->friend_account[i], list->friend_nickname[i]);
                                if (list->friend_state[i] == 1) {
                                    printf("在线\n");
                                } else {
                                    printf("不在线\n");
                                }
                            }
                        } else {
                            printf("你还没有好友!!\n");
                        }
                        printf("按下回车键继续.......");
                        getchar();
                        break;
                    }
            case 10:
                    {
                        send_pack->type = SEND_FMES;
                        printf("请选择你要聊天的对象:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        printf("开始与账号为%d的好友对话\n", send_pack->data.recv_account);
                        while (1) {
                            scanf("%s", send_pack->data.read_buff);
                            if (strcmp(send_pack->data.read_buff, "#bey") == 0) {
                                printf("与账号为%d的好友的聊天结束\n", send_pack->data.recv_account);
                                break;
                            }
                            if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                                my_err("send", __LINE__);
                            }
                            pthread_mutex_lock(&mutex_cli);
                            pthread_cond_wait(&cond_cli, &mutex_cli);
                            pthread_mutex_unlock(&mutex_cli);
                            if (strcmp(send_pack->data.write_buff, "#fail") == 0) {
                                printf("没有账号为%d的好友\n", send_pack->data.recv_account);
                                break;
                            }
                        }
                        send_pack->data.recv_account = 0;
                        printf("按下回车键个继续...");
                        getchar();
                        getchar();
                        break;
                    }
            case 11:
                    {
                        if (box->talk_number == 0) {
                            printf("你没有未看的好友消息!\n");
                        } else {
                            for (int i = 0; i < box->talk_number; ++i) {
                                printf("账号%d:%s\n", box->send_account[i], box->read_buff[i]);
                            }
                            box->talk_number = 0;
                        }
                        printf("按下回车继续......");
                        getchar();
                        break;
                    }
            case 12:
                    {
                        send_pack->type = SEND_GMES;
                        printf("请输入你要聊天的群号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        printf("开始发言:\n");
                        while (1) {
                            scanf("%s", send_pack->data.read_buff);
                            getchar();
                            if (strcmp(send_pack->data.read_buff, "#bey") == 0) {
                                printf("在群%d的发言结束\n", send_pack->data.recv_account);
                                break;
                            }
                            if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                                my_err("send", __LINE__);
                            }
                            pthread_mutex_lock(&mutex_cli);
                            pthread_cond_wait(&cond_cli, &mutex_cli);
                            pthread_mutex_unlock(&mutex_cli);
                            if (strcmp(send_pack->data.write_buff, "#fail") == 0) {
                                printf("没有群号为%d的群\n", send_pack->data.recv_account);
                                break;
                            }
                        }
                        send_pack->data.recv_account = 0;
                        printf("按下回车键个继续...");
                        getchar();
                        break;
                    }
            case 13:
                    {
                        send_pack->type = ADD_GROUP;
                        printf("请输入你想加的群的群号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("加入群%d成功!\n", send_pack->data.recv_account);
                        } else {
                            printf("没有群号为%d的群!或你已加入该群!\n", send_pack->data.recv_account);
                        }
                        printf("按下回车键继续......");
                        getchar();
                        break;
                    }
            case 14:
                    {
                        send_pack->type = CREATE_GROUP;
                        printf("请输入你要创建群的名称:\n");
                        scanf("%s", send_pack->data.recv_user);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("创建群成功!!\n");
                            printf("群号%d\t群名%s\n", send_pack->data.recv_account, send_pack->data.recv_user);
                        } else {
                            printf("创建失败!!\n");
                        }
                        printf("按下回车键继续.....");
                        getchar();
                        break;
                    }
            case 15:
                    {
                        send_pack->type = EXIT_GROUP;
                        printf("请输入你要退出的群的群号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("已退出群%d!!!\n", send_pack->data.recv_account);
                        } else {
                            printf("你没有加入这个群!!\n");
                        }
                        printf("按下回车键继续......");
                        getchar();
                        break;
                    }
            case 16:
                    {
                        send_pack->type = SET_ADMIN;
                        printf("请输入群号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        printf("输入要被设置为管理员的群员账号:\n");
                        scanf("%s", send_pack->data.read_buff);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("账号为%s的成员被设置为群%d的管理员!!\n", send_pack->data.read_buff, send_pack->data.recv_account);
                        } else {
                            printf("群%d里面没有%s这个成员!!\n", send_pack->data.recv_account, send_pack->data.read_buff);
                        }
                        printf("按下回车继续.......");
                        getchar();
                        break;
                    }
            case 17:
                    {
                        send_pack->type = DEL_ADMIN;
                        printf("请输入群号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        printf("输入要被取消管理员的群员账号:\n");
                        scanf("%s", send_pack->data.read_buff);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("账号为%s的成员被取消为群%d的管理员!!\n", send_pack->data.read_buff, send_pack->data.recv_account);
                        } else {
                            printf("群%d里面没有%s这个成员!!\n", send_pack->data.recv_account, send_pack->data.read_buff);
                        }
                        printf("按下回车继续.......");
                        getchar();
                        break;
                    }
            case 18:
                    {
                        send_pack->type = LOOK_MEMBER;
                        printf("输入你想查看的群:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (member_list->group_member_number == 0) {
                            printf("没有群号为%d的群!!!\n", recv_pack->data.recv_account);
                            printf("按下回车键继续.......");
                            getchar();
                            break;
                        }
                        for (int i = 0; i < member_list->group_member_number; ++i) {
                            printf("%d\t%-20s\t", member_list->group_member_account[i], member_list->group_member_nickname[i]);
                            if (member_list->group_member_state[i] == 1) {
                                printf("群主\n");
                            } else if (member_list->group_member_state[i] == 2) {
                                printf("管理员\n");
                            } else {
                                printf("底层群员\n");
                            }
                        }
                        printf("输入回车继续.......");
                        getchar();
                        break;
                    }
            case 19:
                    {
                        struct stat buf;
                        int fd;
                        send_pack->type = SEND_FILE;
                        printf("请输入你要发送文件的对象:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        printf("请输入你想要发送的文件的绝对路径(以'/'开头):\n");
                        scanf("%s", send_pack->data.write_buff);
                        getchar();
                        if (lstat(send_pack->data.write_buff, &buf) < 0) {
                            printf("文件名输入错误\n");
                            printf("按下回车继续......");
                            getchar();
                            break;
                        }
                        if ((fd = open(send_pack->data.write_buff, O_RDONLY)) < 0) {
                            printf("文件打开失败!!\n");
                            printf("按下回车继续.....");
                            getchar();
                            break;
                        }
                        sing = 0;
                        send_pack->data.cont = 0;
                        memset(send_pack->data.read_buff, 0, sizeof(send_pack->data.read_buff));
                        while (read(fd, send_pack->data.read_buff, 1023) > 0) {
                            if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                                my_err("send", __LINE__);
                            }
                            printf("正在发送...%d\n", send_pack->data.cont);
                            memset(send_pack->data.read_buff, 0, sizeof(send_pack->data.read_buff));    
                            pthread_mutex_lock(&mutex_cli);
                            while (sing == 0) {
                                pthread_cond_wait(&cond_cli, &mutex_cli);
                            }
                            pthread_mutex_unlock(&mutex_cli);
                            sing = 0;
                            send_pack->data.cont++;
                        }
                        close(fd);
                        printf("$$$\n");
                        send_pack->type = OK_FILE;
                        sing = 0;
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        printf("&&\n");
                        pthread_mutex_lock(&mutex_cli);
                        while (sing == 0) {   
                            pthread_cond_wait(&cond_cli, &mutex_cli);
                        }
                        pthread_mutex_unlock(&mutex_cli);
                        sing = 0;
                        printf("发送成功!!\n");
                        printf("按下回车键继续.....");
                        getchar();
                        break;
                    }
            case 20:
                    {
                        printf("请输入你要查看的好友:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        send_pack->type = READ_MESSAGE;
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (message->number == 0) {
                            printf("你和他之间还没有聊天记录!!\n");
                        } else {
                           for (int i = 0; i < message->number; ++i) {
                               printf("%d---->%d:\t%s\n", message->send_user[i], message->recv_user[i], message->message[i]);
                            }
                        }
                        printf("按下回车键继续.....");
                        getchar();
                        getchar();
                        break;
                    }
            case 21:
                    {
                        send_pack->type = DEL_MESSAGE;
                        printf("请输入要删除聊天记录的好友:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("删除成功!!\n");
                        } else {
                            printf("没有这个好友或与该好友没有记录!\n");
                        }
                        printf("按下回车键继续.....");
                        getchar();
                        break;
                    }
            case 22:
                    {
                        if (box->number == 0) {
                            printf("消息盒子里面没有群消息!!");
                        } else {
                            for (int i = 0; i < box->number; i++) {
                                printf("群号%d 发送人账号%d 消息内容:\t%s\n", box->group_account[i], box->send_account1[i], box->message[i]);    
                            }
                            box->number = 0;
                        }
                        printf("按下回车键继续......");
                        getchar();
                        break;
                    }
            case 23:
                    {
                        send_pack->type = DEL_MEMBER;
                        printf("输入你的群号:\n");
                        scanf("%d", &send_pack->data.recv_account);
                        getchar();
                        printf("请输入你的要删除的成员账号:\n");
                        scanf("%s", send_pack->data.read_buff);
                        getchar();
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (strcmp(send_pack->data.write_buff, "success") == 0) {
                            printf("删除成功!!\n");
                        } else {
                            printf("你没有权限!!!!\n");
                        }
                        printf("按下回车键继续.....");
                        getchar();
                        break;
                    }
            case 24:
                    {
                        send_pack->type = LOOK_GROUP_LIST;
                        if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_wait(&cond_cli, &mutex_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        if (group_list->number == 0) {
                            printf("你还没加群!!\n");
                            printf("按下回车键继续........");
                            getchar();
                            break;
                        }
                        for (int i = 0; i < group_list->number; ++i) {
                            printf("%d\t%-20s\t", group_list->group_account[i], group_list->group_name[i]);
                            if (group_list->group_state[i] == 1) {
                                printf("群主\n");
                            } else if (group_list->group_state[i] == 2){
                                printf("管理员\n");
                            } else {
                                printf("底层群员\n");
                            }
                        }
                        printf("按下回车键继续......");
                        getchar();
                        break;
                    }
            case 25:
                    {
                        send_pack->data.cont = 0;
                        sing = 0;
                        if (file->have == 0) {
                            printf("没有人给你发文件!!\n");
                            printf("按下回车键继续.....");
                            getchar();
                            break;
                        } else {
                            printf("账号%d昵称%s的好友发来%s的文件\n", file->send_account, file->send_nickname, file->filename);
                            printf("请选择:\n1. 接收 2. 拒绝\n");
                            scanf("%d", &choose);
                            getchar();
                            if (choose == 1) {
                                while (1) {        
                                    send_pack->type = READ_FILE;
                                    send_pack->data.recv_account = file->send_account;
                                    memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                                    strcpy(send_pack->data.write_buff, file->filename);
                                    printf("%d\n",send_pack->data.cont);
                                    if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                                        my_err("send", __LINE__);
                                    }
                                    printf("开始接收文件.....");
                                    pthread_mutex_lock(&mutex_cli);
                                    while (sing == 0) {
                                        pthread_cond_wait(&cond_cli, &mutex_cli);
                                    }
                                    pthread_mutex_unlock(&mutex_cli);
                                    send_pack->data.cont++;
                                    sing = 0;
                                    if (strcmp(send_pack->data.write_buff, "ok") == 0) {
                                        printf("文件接收完毕!!!\n");
                                        printf("按下回车键继续......");
                                        getchar();
                                        break;
                                    }
                                }
                            } else {
                                printf("你已拒绝接收这个文件!!\n");
                                printf("按下回车继续......\n");
                                getchar();
                            }
                        }
                        break;
                    }
            case 26:
                    {
                            send_pack->type = EXIT;
                            if (send(*(int *)sock_fd, send_pack, sizeof(PACK), 0) < 0) {
                                my_err("send", __LINE__);
                            }
                            pthread_exit(0);
                            break;
                    }
        }
    }
}

void *thread_box(void *sock_fd) {
    if (recv(*(int *)sock_fd, box, sizeof(BOX), MSG_WAITALL) < 0) {
        my_err("recv", __LINE__);
    }
    pthread_exit(0);
}

void *thread_list(void *sock_fd) {
    memset(list, 0, sizeof(FRIEND));
    if (recv(*(int *)sock_fd, list, sizeof(FRIEND), MSG_WAITALL) < 0) {
        my_err("recv", __LINE__);
    }
    pthread_exit(0);
}

void *thread_recv_fmes(void *sock_fd) {
    if (recv_pack->data.send_account == send_pack->data.recv_account) {
        printf("账号为%d昵称为%s的好友说:\t%s\n", recv_pack->data.send_account, recv_pack->data.send_user, recv_pack->data.read_buff);
    } else if(strcmp(recv_pack->data.write_buff, "ohyeah") == 0){
        printf("来自特别关心%d昵称%s的好友说:\t%s\n", recv_pack->data.send_account, recv_pack->data.send_user, recv_pack->data.read_buff);
    } else {
        box->send_account[box->talk_number] = recv_pack->data.send_account;
        strcpy(box->read_buff[box->talk_number++], recv_pack->data.read_buff);
        printf("消息盒子里来了一条好友消息!\n");
    }
    pthread_exit(0);
}

void *thread_recv_gmes(void *sock_fd) {
    if (recv_pack->data.recv_account == send_pack->data.recv_account) {
        printf("群号%d 群名%s 账号%d 昵称%s:\t%s\n", recv_pack->data.recv_account, recv_pack->data.recv_user, recv_pack->data.send_account, recv_pack->data.send_user, recv_pack->data.read_buff);
    } else {
        printf("消息盒子里来了一条群消息!!\n");
        box->group_account[box->number] = recv_pack->data.recv_account;
        box->send_account1[box->number] = recv_pack->data.send_account;
        strcpy(box->message[box->number++], recv_pack->data.read_buff);
    }
}

/*void *thread_send_f(void *sock_fd) {
    int fd = open(recv_pack->data.write_buff, O_RDONLY);
    memset(recv_pack->data.read_buff, 0, sizeof(recv_pack->data.read_buff));
    while (read(fd, recv_pack->data.read_buff, 1023) > 0) {
        recv_pack->type = SEND_F;
        if (send(*(int *)sock_fd, recv_pack, sizeof(PACK), 0) < 0) {
            my_err("send", __LINE__);
        }
        printf("正在发送文件.....\n");
        memset(recv_pack->data.read_buff, 0, sizeof(recv_pack->data.read_buff));
        pthread_mutex_lock(&mutex_cli);
        while(sing ==0) {
            pthread_cond_wait(&cond_cli, &mutex_cli);
        }
        pthread_mutex_unlock(&mutex_cli); 
        sing = 0;
    }
    pthread_exit(0);
}*/

void *thread_recv_file(void *sock_fd) {
    memset(file, 0, sizeof(file));
    file->send_account = recv_pack->data.send_account;
    strcpy(file->send_nickname, recv_pack->data.send_user);
    strcpy(file->filename, recv_pack->data.write_buff);
    file->have = 1;
    printf("账号%d\t昵称%s\t的好友给你发送了一个%s文件快去接收吧\n", file->send_account, file->send_nickname, file->filename);
    pthread_exit(0);
}

void *thread_read_message(void *sock_fd) {
    if (recv(*(int *)sock_fd, message, sizeof(MESSAGE), MSG_WAITALL) < 0) {
        my_err("recv", __LINE__);
    }
    pthread_exit(0);
}

void *thread_member(void *sock_fd) {
    memset(member_list, 0, sizeof(GROUP));
    if (recv(*(int *)sock_fd, member_list, sizeof(GROUP), MSG_WAITALL) < 0) {
        my_err("recv", __LINE__);
    }
    pthread_exit(0);
}

void *thread_group_list(void *sock_fd) {
    memset(group_list, 0, sizeof(GROUP_G));
    if (recv(*(int *)sock_fd, group_list, sizeof(GROUP_G), MSG_WAITALL) < 0) {
        my_err("recv", __LINE__);
    }
    pthread_exit(0);
}

/*void *thread_read_file(void *sock_fd) {
    memset(recv_pack->data.read_buff, 0, sizeof(recv_pack->data.read_buff));
    if (recv(*(int *)sock_fd, recv_pack, sizeof(PACK), MSG_WAITALL) < 0) {
        my_err("recv", __LINE__);
    }
    int fd = open(recv_pack->data.write_buff"3.c", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IXUSR);
    write(fd, recv_pack->data.read_buff, strlen(recv_pack->data.read_buff));
    close(fd);
    printf("正在接收.......\n");
    recv_pack->type = SEND_F;
    if (send(*(int *)sock_fd, recv_pack, sizeof(PACK), 0) < 0) {
        my_err("send", __LINE__);
    }
    pthread_exit(0);
}*/

void *thread_write(void *sock_fd) {
    pthread_t pid;
    int ret;
    group_list = (GROUP_G *)malloc(sizeof(GROUP_G));
    member_list = (GROUP *)malloc(sizeof(GROUP));
    list = (FRIEND *)malloc(sizeof(FRIEND));
    box = (BOX *)malloc(sizeof(BOX));
    recv_pack = (PACK*)malloc(sizeof(PACK));
    message = (MESSAGE *)malloc(sizeof(MESSAGE));
    group_message = (GROUP_MESSAGE *)malloc(sizeof(GROUP_MESSAGE));
    file = (FLE *)malloc(sizeof(FLE));
    file->have = 0;
    while (1) {
        memset(recv_pack, 0, sizeof(PACK));
        if ((ret = recv(*(int *)sock_fd, recv_pack, sizeof(PACK), MSG_WAITALL)) < 0) {
            my_err("recv", __LINE__);
        }
        switch(recv_pack->type) {
            case EXIT:
                    {
                        printf("end.......\n");
                        pthread_exit(0);
                        break;
                    }
            case EXIT_GROUP:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
        /*    case SEND_F:
                    {
                        pthread_create(&pid, NULL, thread_send_f, sock_fd);
                        pthread_join(pid, NULL);
                        break;
                    }*/
            case FIND_PASSWORD:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case DEL_MEMBER:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case LOOK_GROUP_LIST:
                    {
                        pthread_create(&pid, NULL, thread_group_list, sock_fd);
                        pthread_join(pid, NULL);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
           case SEND_FILE:
                    {
                        pthread_mutex_lock(&mutex_cli);
                        sing = 1;
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
           case RECV_FILE:
                    {
                        memset(file, 0, sizeof(file));
                        file->send_account = recv_pack->data.send_account;
                        strcpy(file->send_nickname, recv_pack->data.send_user);
                        strcpy(file->filename, recv_pack->data.write_buff);
                        file->have = 1;
                        printf("账号%d\t昵称%s\t的好友给你发送了一个%s文件快去接收吧\n", file->send_account, file->send_nickname, file->filename);
                        break; 
                       /* pthread_create(&pid, NULL, thread_recv_file, sock_fd);
                        pthread_join(pid, NULL);
                        break;*/
                    }
            case LOOK_MEMBER:
                    {
                        pthread_create(&pid, NULL, thread_member, sock_fd);
                        pthread_join(pid, NULL);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case OK_FILE:
                    {
                        pthread_mutex_lock(&mutex_cli);
                        sing = 1;
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case READ_FILE:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        int fd = open("3", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IXUSR);
                        write(fd, recv_pack->data.read_buff, 1023);
                        close(fd);
                        pthread_mutex_lock(&mutex_cli);
                        sing = 1;
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case SET_ADMIN:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case DEL_ADMIN:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case CREATE_GROUP:
                    {
                        strcpy(send_pack->data.recv_user, recv_pack->data.recv_user);
                        send_pack->data.recv_account = recv_pack->data.recv_account;
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break; 
                    }
            case LOGIN:
                    {
                        strcpy(send_pack->data.send_user, recv_pack->data.send_user);
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        send_pack->data.send_fd = recv_pack->data.recv_fd;
                        pthread_create(&pid, NULL, thread_box, sock_fd);
                        pthread_join(pid, NULL);
                        printf("离线期间消息盒子中有%d条消息,%d个好友请求,%d条群消息", box->talk_number, box->friend_number, box->number);
                        pthread_mutex_lock(&mutex_cli);
                        sing = 1;
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break; 
                    }
            case DEL_MESSAGE:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case ADD_GROUP:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case ACCOUNT_ERROR:
                    {  
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        sing = 1;
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;  
                    }
            case REGISTERED:
                    {
                        send_pack->data.send_account = recv_pack->data.send_account;
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case CHANGE_PASSWORD:
                    {                          
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case ADD_FRIEND:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case FRIENDS_PLZ:
                    {
                        pthread_mutex_lock(&mutex_cli);
                        box->plz_account[box->friend_number] = recv_pack->data.send_account; 
                        strcpy(box->write_buff[box->friend_number], recv_pack->data.read_buff);
                        box->friend_number++;
                        printf("消息盒子中来了一条好友请求!!!\n");
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case DEL_FRIEND:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case BLACK_FRIEND:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case WHITE_FRIEND:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case CARE_FRIEND:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case DISCARE_FRIEND:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case LOOK_LIST:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        memset(list, 0, sizeof(FRIEND));
                        pthread_create(&pid, NULL, thread_list, sock_fd);
                        pthread_join(pid, NULL);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case SEND_FMES:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
            case SEND_GMES:
                    {
                        memset(send_pack->data.write_buff, 0, sizeof(send_pack->data.write_buff));
                        strcpy(send_pack->data.write_buff, recv_pack->data.write_buff);
                        pthread_mutex_lock(&mutex_cli);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break; 
                    }
            case RECV_GMES:
                    {
                        pthread_create(&pid, NULL, thread_recv_gmes, sock_fd);
                        pthread_join(pid, NULL);                             
                        break;
                    }
            case RECV_FMES:
                    {
                        pthread_create(&pid, NULL, thread_recv_fmes, sock_fd);
                        pthread_join(pid, NULL);                             
                        break;
                    }
            case READ_MESSAGE:
                    {
                        pthread_mutex_lock(&mutex_cli);
                        pthread_create(&pid, NULL, thread_read_message, sock_fd);
                        pthread_join(pid, NULL);
                        pthread_cond_signal(&cond_cli);
                        pthread_mutex_unlock(&mutex_cli);
                        break;
                    }
        }
    }
}


void mask_ctrl_c()
{
    printf("老哥求求你了别ctrl+c暴力退出了!!!!!!!!!\n");
}

int main() {
    int                 sock_fd;
    pthread_t           pid1;
    pthread_t           pid2;
    struct sockaddr_in  seve;
    
    sing = 0;
    pthread_mutex_init(&mutex_cli, NULL);
    pthread_cond_init(&cond_cli, NULL);
    sock_fd = my_accept_cli();
//    signal(SIGINT,mask_ctrl_c);
    pthread_create(&pid1, NULL, thread_read, (void *)&sock_fd);
    pthread_create(&pid2, NULL, thread_write, (void *)&sock_fd);
    pthread_join(pid1, NULL);
    pthread_join(pid2, NULL);
    
	return 0;
}

my_deal.h

#ifndef _MY_DEAL_H
#define _MY_DEAL_H

void *deal(void *recv_pack);


#endif

my_deal.c

#define _MY_DEAL_C

#include "my_deal.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <mysql/mysql.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "my_pack.h"
#include "my_err.h"
#include "my_mysql.h"
#include "my_friends.h"
#include "my_login.h"
#include "my_group.h"
#include "my_talk.h"

void *deal(void *recv_pack) {
    pthread_detach(pthread_self());
	PACK               *pack;
	int                i;
    BOX                *tmp = box_head;
	MYSQL              mysql;
	mysql = accept_mysql();
	pack = (PACK*)recv_pack;
	switch(pack->type)
	{
		case LOGIN:
			{
				if (login(pack, mysql) != 0) {
                    pack->type = ACCOUNT_ERROR;
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
					strcpy(pack->data.write_buff, "password error");
                    if (send(pack->data.recv_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
				} else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "good");
                    int ret;
                    if ((ret = send(pack->data.recv_fd, pack, sizeof(PACK), 0)) < 0) {
                        my_err("send", __LINE__);
                    }
                    while (tmp != NULL) {
                        if (tmp->recv_account == pack->data.send_account) {
                            break;
                        }
                        tmp = tmp->next;
                    }
                    if (tmp == NULL) {
                        tmp = (BOX *)malloc(sizeof(BOX));
                        tmp->recv_account = pack->data.send_account;
                        tmp->talk_number = tmp->friend_number = 0;
                        tmp->number = 0;
                        tmp->next = NULL;
                        if (box_head == NULL) {
                            box_head = box_tail = tmp;
                        } else {
                            box_tail->next = tmp;
                            box_tail = tmp;
                        }
                        if (send(pack->data.recv_fd, tmp, sizeof(BOX), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                    } else {
                        if (send(pack->data.recv_fd, tmp, sizeof(BOX), 0) < 0) {
                            my_err("send", __LINE__);
                        }
                        tmp->friend_number = 0;
                        tmp->talk_number = 0;
                    }
                }
                break;
			}
        case REGISTERED:
            {
                registered(pack, mysql);
                memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                strcpy(pack->data.write_buff, "registered success!!");
                if (send(pack->data.recv_fd, pack, sizeof(PACK), 0) < 0) {
                    my_err("send", __LINE__);
                }
                
                break;
            }
        case CHANGE_PASSWORD:
            {
                if (change_password(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.recv_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.recv_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);        
                    }
                }
                break;
            }
        case ADD_FRIEND:
            {
                if (add_fir(pack, mysql) == 0) {
                    pack->type = ADD_FRIEND;
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.recv_fd, pack, sizeof(PACK) , 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.recv_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);        
                    } 
                }
                break;
            }
        case FRIENDS_PLZ:
            {
                friends_plz(pack, mysql);
                break;
            }
        case DEL_FRIEND:
            {
                if (del_friend(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                }
                break;
            }
        case BLACK_FRIEND:
            {
                if (black_friend(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break;
            }
        case WHITE_FRIEND:
            {
                if (white_friend(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break;
            }
        case CARE_FRIEND:
            {
                if (care_friend(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break;
            }
        case DISCARE_FRIEND:
            {
                if (discare_friend(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break;
            }
        case LOOK_LIST:
            {
                FRIEND *list = look_list(pack, mysql);
                if (list->friend_number != 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                    if (send(pack->data.send_fd, list, sizeof(FRIEND), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                    if (send(pack->data.send_fd, list, sizeof(FRIEND), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                }
                break;       
            }
        case SEND_FMES:
            {
                if (send_fmes(pack, mysql) == -1) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "#fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "#succss");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                }
                break;
            }
        case SEND_GMES:
            {
                if (send_gmes(pack, mysql) == -1) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "#fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "#succss");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                }
                break;
            }
        case READ_MESSAGE:
            {
                read_message(pack, mysql);
                break;
            }
        case DEL_MESSAGE:
            {
                if (del_message(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break;    
            }
        case CREATE_GROUP:
            {
                if (create_group(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    printf("%s\n", pack->data.write_buff);
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break; 
            }
        case ADD_GROUP:
            {
               if (add_group(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    printf("%s\n", pack->data.write_buff);
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break;  
            }
        case EXIT_GROUP:
            {
                if (exit_group(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    printf("%s\n", pack->data.write_buff);
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break; 
            }
        case SET_ADMIN:
            {
                if (set_admin(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    printf("%s\n", pack->data.write_buff);
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break; 
            }
        case DEL_ADMIN:
            {
                if (del_admin(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    printf("%s\n", pack->data.write_buff);
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break; 
            }
        case LOOK_MEMBER:
            {
                look_member(pack, mysql);
                break;
            }
        case LOOK_GROUP_LIST:
            {
                look_group_list(pack, mysql);
                break;
            }
        case FIND_PASSWORD:
            {
                find_password(pack, mysql);
                break;
            }
        case DEL_MEMBER:
            {
                 if (del_member(pack, mysql) == 0) {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "success");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    }
                } else {
                    memset(pack->data.write_buff, 0, sizeof(pack->data.write_buff));
                    strcpy(pack->data.write_buff, "fail");
                    if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                        my_err("send", __LINE__);
                    } 
                }
                break;   
            }
        case SEND_FILE:
            {
                pthread_mutex_lock(&mutex);
                int fd = open("2", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IXUSR);
                write(fd, pack->data.read_buff, 1023);
                close(fd);
                printf("%d\n", pack->data.cont);
                if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                    my_err("send", __LINE__);
                }
                pthread_mutex_unlock(&mutex);
                break;
            }
        case READ_FILE:
            {
               pthread_mutex_lock(&mutex);
               int fd = open("2", O_RDONLY);
               lseek(fd, 1023*pack->data.cont, SEEK_SET);
               memset(pack->data.read_buff, 0, sizeof(pack->data.read_buff));
               if (read(fd, pack->data.read_buff, 1023) == 0) {
                   strcpy(pack->data.write_buff, "ok");
               }
               if (send(pack->data.send_fd, pack, sizeof(PACK), 0) < 0) {
                    my_err("send", __LINE__);
               }
               close(fd);
               pthread_mutex_unlock(&mutex);
               break;
            }
        case OK_FILE:
            {
                    printf("sssssss^^\n");
                ok_file(pack, mysql);
                break;
            }
       
	}
	close_mysql(mysql);
}

my_err.h

#ifndef _MY_ERR_H
#define _MY_ERR_H

void my_err(char *err_string , int line);

#endif

my_err.c


#define _MY_ERR_C

#include "my_err.h"

#include <stdlib.h>
#include <stdio.h>

void my_err(char *err_string , int line) {
    fprintf(stdout,"line:%d",line);
    perror(err_string);
    exit(1);
}

my_friends.h


#ifndef _MY_FRIENDS_H
#define _MY_FRIENDS_H
#include <mysql/mysql.h>
#include "my_pack.h"

int add_fir(PACK *pack, MYSQL mysql1);
int del_friend(PACK *pack, MYSQL mysql1);
int friends_plz(PACK *pack, MYSQL mysql1);
int black_friend(PACK *pack, MYSQL mysql1);
int white_friend(PACK *pack, MYSQL mysql1);
int care_friend(PACK *pack, MYSQL mysql1);
int discare_friend(PACK *pack, MYSQL mysql1);
FRIEND *look_list(PACK *pack, MYSQL mysql1);

#endif

my_friends.c

#define _MY_FRIENDS_C

#include "my_friends.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "my_mysql.h"
#include "my_pack.h"
#include "my_err.h"

int add_fir(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    MYSQL_RES       *result;
    MYSQL_ROW       row, row1;
    BOX             *tmp = box_head;
    int             ret;
    char            need[100];
    
    sprintf(need, "select *from user_data where account = %d", recv_pack->data.recv_account);
    pthread_mutex_lock(&mutex);
    ret = mysql_query(&mysql, need);
    if (!ret) {
        result = mysql_store_result(&mysql);
        row = mysql_fetch_row(result);
        if (row == NULL) {
            pthread_mutex_unlock(&mutex);
            return -1;
        }
        memset(need, 0, sizeof(need));
        sprintf(need, "select *from friends where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
        ret = mysql_query(&mysql, need);
        if (!ret) {
            // 如果可以查到数据说明对方已经是好友了 
            result = mysql_store_result(&mysql);
            row1 = mysql_fetch_row(result);
            if (row1 != NULL) {
                pthread_mutex_unlock(&mutex);
                return -1;
            }
            memset(need, 0, sizeof(need));
            sprintf(need, "账号为%d,昵称为%s的用户发来好友请求\n", recv_pack->data.send_account, recv_pack->data.send_user);
            if (atoi(row[3]) == 0) {
                while (tmp) {
                    if (tmp->recv_account == recv_pack->data.recv_account) {
                        break;
                    }
                    tmp = tmp->next;
                }
                if (tmp != NULL) {
                    tmp->plz_account[tmp->friend_number] = recv_pack->data.send_account;
                    strcpy(tmp->write_buff[tmp->friend_number], need);
                    tmp->friend_number++;
                } else {
                    tmp = (BOX *)malloc(sizeof(BOX));
                    tmp->recv_account = recv_pack->data.recv_account;
                    tmp->friend_number = 0;
                    tmp->talk_number = 0;
                    strcpy(tmp->write_buff[tmp->friend_number], need);
                    tmp->plz_account[tmp->friend_number++] = recv_pack->data.send_account;
                    if (box_head == NULL) {
                        box_head = box_tail = tmp;
                        box_tail->next = NULL;
                    } else {
                        box_tail->next = tmp;
                        box_tail = tmp;
                        box_tail->next = NULL;
                    }
                }
                pthread_mutex_unlock(&mutex);
                return 0;
            } else {
                recv_pack->data.send_fd = atoi(row[4]);
                strcpy(recv_pack->data.recv_user, row[1]);
                strcpy(recv_pack->data.read_buff, need);
                recv_pack->type = FRIENDS_PLZ;
                if (send(recv_pack->data.send_fd, recv_pack, sizeof(PACK), 0) < 0) {
                    my_err("send", __LINE__);
                } 
                pthread_mutex_unlock(&mutex);
                
                return 0;
            }
        }
    }
}

int friends_plz(PACK *pack, MYSQL mysql1) {
    char            need[100]; 
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    
    pthread_mutex_lock(&mutex);
    sprintf(need, "insert into friends values(%d,%d,0)", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    memset(need, 0, sizeof(need));
    sprintf(need, "insert into friends values(%d,%d,0)", recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);
    
    return 0;
}   
     
int del_friend(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    char            need[100];
    MYSQL_ROW       row;
    MYSQL_RES       *result;

    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from friends where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (row == NULL) {
        pthread_mutex_unlock(&mutex);    
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "delete from friends where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    memset(need, 0, sizeof(need));
    sprintf(need, "delete from friends where user = %d and friend_user = %d", recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);
    
    return 0;
}

int black_friend(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    char            need[100];
    MYSQL_ROW       row;
    MYSQL_RES       *result;
    
    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from friends where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (row == NULL) {
        pthread_mutex_unlock(&mutex);    
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "update friends set realtion = -1 where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);

    return 0;
}

int white_friend(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    char            need[100];
    MYSQL_ROW       row;
    MYSQL_RES       *result;

    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from friends where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (row == NULL) {
        pthread_mutex_unlock(&mutex);    
        return -1;
    }
    if (atoi(row[2]) == OK) {
        pthread_mutex_unlock(&mutex);
        return 0;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "update friends set realtion = 0 where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);

    return 0;
}

int care_friend(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    char            need[100];
    MYSQL_RES       *result;
    MYSQL_ROW       row;

    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from friends where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (row == NULL) {
        pthread_mutex_unlock(&mutex);    
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "update friends set realtion = 1 where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);
}

int discare_friend(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    char            need[100];
    MYSQL_RES       *result;
    MYSQL_ROW       row;

    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from friends where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (row == NULL) {
        pthread_mutex_unlock(&mutex);    
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "update friends set realtion = 0 where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);
}

FRIEND *look_list(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    char            need[100];
    MYSQL_RES       *result, *result1;
    MYSQL_ROW       row, row1;
    FRIEND          *list;

    list = (FRIEND *)malloc(sizeof(FRIEND));
    list->friend_number = 0;
    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from friends where user = %d", recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    while (row = mysql_fetch_row(result)) {
        list->friend_account[list->friend_number] = atoi(row[1]);
        memset(need, 0, sizeof(need));
        sprintf(need, "select *from user_data where account = %d", atoi(row[1]));
        mysql_query(&mysql, need);
        result1 = mysql_store_result(&mysql);
        row1 = mysql_fetch_row(result1);
        strcpy(list->friend_nickname[list->friend_number], row1[1]);
        list->friend_state[list->friend_number++] = atoi(row1[3]);
    }
    if (list->friend_number == 0) {
        pthread_mutex_unlock(&mutex);
        return list;
    } else {
        pthread_mutex_unlock(&mutex);
        return list;
    }
}

my_group.h

#ifndef _MY_GROUP_H
#define _MY_GROUP_H

#include "my_pack.h"

#include <mysql/mysql.h>

// 创建群
int create_group(PACK *pack, MYSQL mysql1);
// 加群
int add_group(PACK *pack, MYSQL mysql1);
// 退群
int exit_group(PACK *pack, MYSQL mysql1);
// 设置管理员
int set_admin(PACK *pack, MYSQL mysql1);
// 取消管理员
int del_admin(PACK *pack, MYSQL mysql1);
// 查看群成员
int look_member(PACK *pack, MYSQL mysql1);
// 查看已经加入的群
int look_group_list(PACK *pack, MYSQL mysql1);
// 群t人
int del_member(PACK *pack, MYSQL mysql1);

#endif

my_group.c

#define _MY_GROUP_C

#include "my_group.h"

#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "my_err.h"
#include "my_pack.h"
#include "my_mysql.h"


int create_group(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    char            need[200];
    PACK            *recv_pack = pack;
    FILE            *fp;
    int             group_number;

    pthread_mutex_lock(&mutex);
    fp = fopen("group_number.txt", "r");
    fread(&group_number, sizeof(int), 1, fp);
    fclose(fp);
    sprintf(need, "insert into groups values(%d,\"%s\",1)", group_number++, recv_pack->data.recv_user);
    mysql_query(&mysql, need);
    recv_pack->data.recv_account = group_number - 1;
    fp = fopen("group_number.txt", "w");
    fwrite(&group_number, sizeof(int), 1, fp);
    fclose(fp);
    memset(need, 0, sizeof(need));
    sprintf(need, "insert into group_members values(%d,\"%s\",%d,\"%s\",1)", recv_pack->data.recv_account, recv_pack->data.recv_user, recv_pack->data.send_account, recv_pack->data.send_user);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);

    return 0;
}

int add_group(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[200];
    PACK            *recv_pack = pack;
    int             num;

    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from groups where group_account = %d", recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    strcpy(recv_pack->data.recv_user, row[1]);
    num = atoi(row[2]);
    memset(need, 0, sizeof(need));
    sprintf(need, "select *from group_members where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "insert into group_members values(%d,\"%s\",%d,\"%s\",0)", recv_pack->data.recv_account, recv_pack->data.recv_user, recv_pack->data.send_account, recv_pack->data.send_user);
    mysql_query(&mysql, need);
    memset(need, 0, sizeof(need));
    sprintf(need, "update groups set group_state = %d where group_account = %d", num+1, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);

    return 0;
}

int exit_group(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[100];
    int             num;

    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from groups where group_account = %d", recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    num = atoi(row[2]);
    memset(need, 0, sizeof(need));
    sprintf(need, "select *from group_members where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "delete from group_members where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    memset(need, 0, sizeof(need));
    sprintf(need, "update groups set group_mumber_number = %d where group_account = %d", num-1, recv_pack->data.recv_account);
    mysql_query(&mysql, need);

    pthread_mutex_unlock(&mutex);
    
    return 0;
}

int set_admin(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[200];
    int             account;

    pthread_mutex_lock(&mutex);
    account = atoi(recv_pack->data.read_buff);
    sprintf(need, "select *from group_members where group_account = %d and group_member_account = %d and group_state = 1", recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex_cli);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "select *from group_members where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "update group_members set group_state = 2 where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);

    return 0;
}

int del_admin(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    int             account;
    char            need[150];
    
    account = atoi(recv_pack->data.read_buff);
    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from group_members where group_account = %d and group_member_account = %d and group_state = 1", recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex_cli);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "select *from group_members where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "update group_members set group_state = 0 where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, account);
    mysql_query(&mysql, need);
    pthread_mutex_unlock(&mutex);

    return 0;
}

int look_member(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[100];
    GROUP           *group;

    pthread_mutex_lock(&mutex);
    group = (GROUP *)malloc(sizeof(GROUP));
    group->group_member_number = 0;
    sprintf(need, "select *from group_members where group_account = %d", recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    while (row = mysql_fetch_row(result)) {
        group->group_member_account[group->group_member_number] = atoi(row[2]);
        strcpy(group->group_member_nickname[group->group_member_number], row[3]);
        group->group_member_state[group->group_member_number++] = atoi(row[4]);
    }
    if (send(recv_pack->data.send_fd, recv_pack, sizeof(PACK), 0) < 0) {
        my_err("send", __LINE__);
    }
    if (send(recv_pack->data.send_fd, group, sizeof(GROUP), 0) < 0) {
        my_err("send", __LINE__);
    }
    pthread_mutex_unlock(&mutex);

    return 0;
}

int look_group_list(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[200];
    GROUP_G         *group;
    
    group = (GROUP_G *)malloc(sizeof(GROUP_G));
    group->number = 0;
    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from group_members where group_member_account = %d", recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    while (row = mysql_fetch_row(result)) {
        group->group_account[group->number] = atoi(row[0]);
        strcpy(group->group_name[group->number], row[1]);
        group->group_state[group->number++] = atoi(row[4]);
    }
    if (send(recv_pack->data.send_fd, recv_pack, sizeof(PACK), 0) < 0) {
        my_err("send", __LINE__);
    }
    if (send(recv_pack->data.send_fd, group, sizeof(GROUP_G), 0) < 0) {
        my_err("send", __LINE__);
    }
    pthread_mutex_unlock(&mutex);

    return 0;
}

int del_member(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[200];
    int             account;

    account = atoi(recv_pack->data.read_buff);
    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from group_members where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row || atoi(row[4]) == 0) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "delete from group_members where group_account = %d and group_member_account = %d", recv_pack->data.recv_account, account);
    mysql_query(&mysql, need);

    pthread_mutex_unlock(&mutex);
    return 0;
}

my_login.h

#ifndef _MY_LOGIN_H
#define _MY_LOGIN_H

#include "my_pack.h"
#include <mysql/mysql.h>

int login(PACK *pack, MYSQL mysql1);
int registered(PACK *pack, MYSQL mysql1);
int change_password(PACK *pack, MYSQL mysql1);
int find_password(PACK *pack, MYSQL mysql1);

#endif

my_login.c

#define _MY_LOGIN_C

#include "my_login.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <mysql/mysql.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "my_err.h"
#include "my_pack.h"
#include "my_mysql.h"


int login(PACK *pack, MYSQL mysql1) {
    int                i;
    int                ret;
    int                cont = 0;
    char               inedx[100];	
    PACK               *recv_pack = pack;
    MYSQL              mysql = mysql1;
    MYSQL_RES          *result = NULL;
    MYSQL_ROW          row;

    sprintf(inedx, "select *from user_data where account = %d", recv_pack->data.send_account);
    pthread_mutex_lock(&mutex);	
    ret = mysql_query(&mysql, inedx);

    if (!ret) {
        result = mysql_store_result(&mysql);
        row = mysql_fetch_row(result);
        if (row == NULL) {
            pthread_mutex_unlock(&mutex);
            return -1;
        }
        if (strcmp(row[2], recv_pack->data.read_buff) == 0) {
            strcpy(recv_pack->data.send_user, row[1]);
            memset(inedx, 0, sizeof(inedx));
            pack->data.recv_fd = atoi(row[4]);
            sprintf(inedx, "update user_data set user_state = 1 where account = %d", pack->data.send_account);
            mysql_query(&mysql, inedx);
            mysql_free_result(result);
            pthread_mutex_unlock(&mutex);
                
            return 0;
        } else {      
            pack->data.recv_fd = atoi(row[4]);
            pthread_mutex_unlock(&mutex);
            return -1;
        }
    } else {
        printf("query fail\n");
        pthread_mutex_unlock(&mutex);
        
        return -1;
    }    
}

int registered(PACK *pack, MYSQL mysql1) {
    FILE               *fp;
    MYSQL              mysql = mysql1;	
    char               need[100];
    PACK               *recv_pack = pack;
    int                user_number;
	
    pthread_mutex_lock(&mutex);	
    /* 在user_number.txt文件中存放着用户的个数,数量从1000000开始 */
    if ((fp = fopen("user_number.txt", "r")) == NULL) {
        printf("打开文件失败\n");
        exit(-1);
    }
    fread(&user_number, sizeof(int), 1, fp);
	
    sprintf(need, "insert into user_data values(%d,\"%s\",\"%s\",%d,%d)", user_number++, recv_pack->data.send_user, recv_pack->data.read_buff, 0, recv_pack->data.recv_fd);
    recv_pack->data.send_account = user_number-1;
    mysql_query(&mysql, need);
    fclose(fp);
    if ((fp = fopen("user_number.txt", "w")) == NULL) {
        printf("打开文件失败\n");
        exit(-1);
    }
    fwrite(&user_number, sizeof(int), 1, fp);
    fclose(fp);
    pthread_mutex_unlock(&mutex);

    return 0;
}

int change_password(PACK *pack, MYSQL mysql1) {
    MYSQL_RES          *result = NULL;
    PACK               *recv_pack = pack;
    MYSQL              mysql = mysql1;
    char               need[100];
    MYSQL_ROW          row;

    sprintf(need, "select *from user_data where account = %d", recv_pack->data.send_account);
    pthread_mutex_lock(&mutex);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (row) {
        if (strcmp(recv_pack->data.read_buff, row[2]) == 0) {
            recv_pack->data.recv_fd = atoi(row[4]);
            memset(need, 0, sizeof(need));
            sprintf(need, "update user_data set password = \"%s\" where account = %d", recv_pack->data.write_buff, recv_pack->data.send_account);
            mysql_query(&mysql, need);
            pthread_mutex_unlock(&mutex);
            
            return 0;
        } else {
            pthread_mutex_unlock(&mutex);
            
            return -1;
        }
    } else {
        pthread_mutex_unlock(&mutex);

        return -1;
    }

    return -1;
}

int find_password(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[150];
    PACK            *recv_pack = pack;
    int             cont = 0;

    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from friends where user = %d", recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    while (row = mysql_fetch_row(result)) {
        cont++;
    }
    if (cont != recv_pack->data.recv_account) {
        strcpy(recv_pack->data.write_buff, "你找不回来你的密码了!!");
        memset(need, 0, sizeof(need));
        sprintf(need, "select *from user_data where account = %d", recv_pack->data.send_account);
        mysql_query(&mysql, need);
        result = mysql_store_result(&mysql);
        row = mysql_fetch_row(result);
        if (!row) {
            strcpy(recv_pack->data.write_buff, "你的账号都是错的哦!!");
        }
        if (send(recv_pack->data.recv_fd, recv_pack, sizeof(PACK), 0) < 0) {
            my_err("send", __LINE__);
        }
    } else {
        memset(need, 0, sizeof(need));
        sprintf(need, "select *from user_data where account = %d", recv_pack->data.send_account);
        mysql_query(&mysql, need);
        result = mysql_store_result(&mysql);
        row = mysql_fetch_row(result);
        if (!row) {
            strcpy(recv_pack->data.write_buff, "你的账号都是错的哦!!");
        } else {
            sprintf(recv_pack->data.write_buff, "你的密码是%s", row[2]);
        }
        if (send(recv_pack->data.recv_fd, recv_pack, sizeof(PACK), 0) < 0) {
            my_err("send", __LINE__);
        }
    }
    
    pthread_mutex_unlock(&mutex);
    return 0;
}

my_mune.h

#ifndef _MY_MUNE_H
#define _MY_MUNE_H

void login_mune(void);
void mune(void);

#endif

my_mune.c这块真的太傻比了为了偷懒写在了一起,太不方便了

#define _MY_MUNE_C

#include "my_mune.h"

#include <stdio.h>


void login_mune() {
    printf("\033c");

    printf("                          ------------------------------------------------------------------------------                   \n\n\n\n\n\n");
    printf("                                                    1.   登录                                                                    \n\n\n");
    printf("                                                    2.   注册                                                                    \n\n\n");
    printf("                                                    3.   找回密码                                                                \n\n\n");
    printf("                                                    4.   优雅退出                                                                \n\n\n");
    printf("                          ------------------------------------------------------------------------------                         \n\n\n");
    printf("请选择:\n");
}


void mune() {
    printf("\033c");
    printf("登陆成功!!!\n");

    printf("                           ---------------------------------------------------------------------------                       \n\n\n\n");
    printf("                                                    1.   修改密码                                                                \n");
    printf("                                                    2.   加好友                                                                  \n");
    printf("                                                    3.   删除好友                                                                \n");
    printf("                                                    4.   处理好友请求                                                            \n");
    printf("                                                    5.   拉黑好友                                                                \n");
    printf("                                                    6.   将好友从黑名单中取出                                                    \n");
    printf("                                                    7.   设置好友特别关心                                                        \n");
    printf("                                                    8.   取消好友特别关心                                                        \n");
    printf("                                                    9.   显示好友列表                                                            \n");
    printf("                                                    10.  私聊                                                                    \n");
    printf("                                                    11.  查看好友消息                                                            \n");
    printf("                                                    12.  群聊                                                                    \n");
    printf("                                                    13.  加群                                                                    \n");
    printf("                                                    14.  创建群聊                                                                \n");
    printf("                                                    15.  退出群                                                                  \n");
    printf("                                                    16.  设置管理员                                                              \n");
    printf("                                                    17.  删除管理员                                                              \n");
    printf("                                                    18.  查看群成员                                                              \n");
    printf("                                                    19.  传送文件                                                                \n");
    printf("                                                    20.  查看好友聊天记录                                                        \n");
    printf("                                                    21.  删除好友聊天记录                                                        \n");
    printf("                                                    22.  查看群消息                                                              \n");
    printf("                                                    23.  群t人                                                                   \n");
    printf("                                                    24.  查看已加入的群                                                          \n");
    printf("                                                    25.  接受文件                                                                \n");
    printf("                                                    26.  优雅退出                                                                \n");
    printf("                           --------------------------------------------------------------------------                               ");
}

my_mysql.h

#ifndef _MY_MYSQL_H
#define _MY_MYSQL_H
#include <mysql/mysql.h>

MYSQL accept_mysql(void);
int close_mysql(MYSQL mysql);

#endif

my_mysql.c

#define _MY_MYSQL_C

#include "my_mysql.h"

#include <mysql/mysql.h>
#include <stdio.h>

#include "my_err.h"
#include "my_pack.h"


MYSQL accept_mysql(void) {
    MYSQL               mysql;
	
    if (NULL == mysql_init(&mysql)) {
        my_err("mysqlinit", __LINE__);
	}

    // 初始化数据库
    if (mysql_library_init(0, NULL, NULL) != 0) {
        my_err("mysqllibrary_init", __LINE__);
    }

    //连接数据库
    if (NULL == mysql_real_connect(&mysql, "127.0.0.1", "root", "520520cw...", "happy", 0, NULL, 0)) {
        my_err("mysqlrealconnect", __LINE__);
    }

    //设置中文字符集
    if (mysql_set_character_set(&mysql, "utf8") < 0) {
        my_err("mysqlsetcharacter_set", __LINE__);
    }
    
    return mysql;
}

int close_mysql(MYSQL mysql) {
    mysql_close(&mysql);
    mysql_library_end();
    
    return 0;
}

my_pack.h

#ifndef _MY_PACK_H
#define _MY_PACK_H
#include <pthread.h>

#define MAX_FRIEND 500
// 登录
#define LOGIN 1
// 注册
#define REGISTERED 2
// 找回密码
#define FIND_PASSWORD 3
// 修改密码
#define CHANGE_PASSWORD 4
// 添加好友
#define ADD_FRIEND 5
// 删除好友
#define DEL_FRIEND 6
// 查看好友列表
#define LOOK_LIST 7
// 发消息
#define SEND_FMES 8
// 创建群
#define CREATE_GROUP 9
// 加入群
#define ADD_GROUP 10
// 退出群
#define EXIT_GROUP 11
// 删除群成员
#define DEL_MEMBER 12
// 设置管理员
#define SET_ADMIN 13
// 删除管理员
#define DEL_ADMIN 14
// 发送群消息
#define SEND_GMES 15
// 查看加入的群
#define LOOK_GROUP 16
// 群主删除群
#define DIS_GROUP 17
// 发送文件
#define SEND_FILE 18
// 好友请求
#define FRIENDS_PLZ 19
// 黑名单
#define BLACK_FRIEND 20
// 取消黑名单
#define WHITE_FRIEND 21
// 特别关心
#define CARE_FRIEND 22
// 取消特关
#define DISCARE_FRIEND 23
#define MAXIN 1024
#define EXIT -1
#define ACCOUNT_ERROR -2
#define CARE 1
#define OK 0
#define RECV_FMES 24
#define BLACK -1
#define READ_MESSAGE 25
#define READ_GMES 26
#define RECV_GMES 27
#define DEL_MESSAGE 28
#define LOOK_MEMBER 29
#define LOOK_GROUP_LIST 30
#define RECV_FILE 31
#define READ_FILE 32
#define OK_FILE 33
#define SEND_F 34

pthread_mutex_t mutex;
pthread_mutex_t mutex_cli;
pthread_cond_t cond_cli;
pthread_cond_t cond;

typedef struct {
    int               cont;
    int               send_fd;
    int               recv_fd;
    int               send_account;
    int               recv_account;
    char              send_user[50];
    char              recv_user[50];
    char              read_buff[MAXIN];
    char              write_buff[MAXIN];
} DATA;

typedef struct {
    int               friend_number;
    int               friend_account[500];
    char              friend_nickname[500][20];
    int               friend_state[500];
} FRIEND;

typedef struct {
    int               number;
    char              message[500][MAXIN];
    int               send_user[500];
    int               recv_user[500];
} MESSAGE;

typedef struct {
    int               group_account;
    int               message_number;
    int               send_account[500];
    char              message[500][MAXIN];
} GROUP_MESSAGE;

typedef struct {
    int               group_account;
    int               group_member_number;
    int               group_member_account[500];	
    char              group_member_nickname[500][20];
    int               group_member_state[500];
} GROUP;

typedef struct {
    int               type;
    DATA              data;
} PACK;

typedef struct {
    int               group_account[100];
    char              group_name[100][20];
    int               number;
    int               group_state[100];
} GROUP_G;

typedef struct {
    char              filename[50];
    int               send_account; 	
    char              send_nickname[50];
    int               have;
} FLE;

// 消息盒子
typedef struct BOX {
    // 接受消息的人的账号
    int               recv_account;
    // 发送消息人的账号
    int               send_account[500];
    // 发送好友请求人的账号
    int               plz_account[500];
    // 发送的消息
    char              read_buff[500][MAXIN];
    // 发送的请求
    char              write_buff[500][100];
    // 消息数量
    int               talk_number;
    // 请求数量
    int               friend_number;
    // 群里发送消息的人
    int               send_account1[500];
    // 消息内容
    char              message[500][MAXIN];
    // 群消息数量
    int               number;
    // 群号
    int               group_account[500];
    struct BOX        *next;
} BOX;


BOX *box_head;
BOX *box_tail;

#endif

my_pack.c

#define _MY_PACK_C

#include "my_pack.h"

BOX *box_head = NULL;
BOX *box_tail = NULL;

my_talk.h

#ifndef _MY_TALK_H
#define _MY_TALK_H
#include "my_pack.h"
#include <mysql/mysql.h>

int send_fmes(PACK *pack, MYSQL mysql1);
int read_message(PACK *pack, MYSQL mysql1);
int del_message(PACK *pack, MYSQL msyql1);
int send_gmes(PACK *pack, MYSQL mysql1);
// int send_file(PACK *pack, MYSQL mysql1);
// int read_file(PACK *pack, MYSQL mysql1);
int ok_file(PACK *pack, MYSQL msyql1); 

#endif

my_talk.c

#define _MY_TALK_C

#include "my_talk.h"

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <mysql/mysql.h>

#include "my_pack.h"
#include "my_err.h"
#include "my_mysql.h"
#include "my_friends.h"
#include "my_login.h"

int send_fmes(PACK *pack, MYSQL mysql1) {
    char            need[100];
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    BOX             *tmp;

    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from user_data where account = %d", recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    strcpy(recv_pack->data.recv_user, row[1]);
    if ((atoi(row[3]) == 1)) {
        recv_pack->type = RECV_FMES;
        recv_pack->data.recv_fd = atoi(row[4]);
        memset(need, 0, sizeof(need));
        sprintf(need, "select *from friends where user = %d", recv_pack->data.recv_account);
        mysql_query(&mysql, need);
        result = mysql_store_result(&mysql);
        while (row = mysql_fetch_row(result)) {
            if (atoi(row[1]) != recv_pack->data.send_account) {
                continue;
            }
            if (atoi(row[2]) == BLACK) {
               recv_pack->type = SEND_FMES;
               pthread_mutex_unlock(&mutex);
               return -1;
            } else if (atoi(row[2]) == CARE) {
                memset(recv_pack->data.write_buff, 0, sizeof(recv_pack->data.read_buff));
                strcpy(recv_pack->data.write_buff, "ohyeah");
                if (send(recv_pack->data.recv_fd, recv_pack, sizeof(PACK), 0) < 0) {
                    my_err("send", __LINE__);
                }
                memset(recv_pack->data.write_buff, 0, sizeof(recv_pack->data.write_buff));
                memset(need, 0, sizeof(need));
                sprintf(need, "insert into chat_messages values(%d,%d,\"%s\",1,1)", recv_pack->data.send_account, recv_pack->data.recv_account,recv_pack->data.read_buff);
                mysql_query(&mysql, need);
                break;
            } else if(atoi(row[2]) == OK){
                if (send(recv_pack->data.recv_fd, recv_pack, sizeof(PACK), 0) < 0) {
                    my_err("send", __LINE__);
                }
                memset(need, 0, sizeof(need));
                sprintf(need, "insert into chat_messages values(%d,%d,\"%s\",1,1)", recv_pack->data.send_account, recv_pack->data.recv_account, recv_pack->data.read_buff);
                mysql_query(&mysql, need);
                break;
            }
        }
        if (!row) {
            pthread_mutex_unlock(&mutex);
            recv_pack->type = SEND_FMES;
            return -1;
        }
    } else {
        tmp = box_head;
        while (tmp != NULL) {
            if (tmp->recv_account = recv_pack->data.recv_account) {
                tmp->send_account[tmp->talk_number] = recv_pack->data.send_account;
                strcpy(tmp->read_buff[tmp->talk_number++], recv_pack->data.read_buff);
                memset(need, 0, sizeof(need));
                sprintf(need, "insert into chat_messages values(%d,%d,\"%s\",1,1)", recv_pack->data.send_account, recv_pack->data.recv_account,recv_pack->data.read_buff);
                mysql_query(&mysql, need);
                break;
            }
            tmp = tmp->next;
        }
    }
    pthread_mutex_unlock(&mutex);
    recv_pack->type = SEND_FMES;

    return 0;
}

int read_message(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql =  mysql1;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[200];
    MESSAGE         *message;

    pthread_mutex_lock(&mutex);
    message = (MESSAGE *)malloc(sizeof(MESSAGE));
    message->number = 0;
    sprintf(need, "select *from chat_messages where send_user = %d and recv_user = %d and send_can_look = 1 union select *from chat_messages where send_user = %d and recv_user = %d and recv_can_look = 1", recv_pack->data.send_account, recv_pack->data.recv_account, recv_pack->data.recv_account, recv_pack->data.send_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    while (row = mysql_fetch_row(result)) {
       message->send_user[message->number] = atoi(row[0]);
       message->recv_user[message->number] = atoi(row[1]);
       strcpy(message->message[message->number++], row[2]);
    }
    if (send(recv_pack->data.send_fd, recv_pack, sizeof(PACK), 0) < 0) {
        my_err("send", __LINE__);
    }
    if (send(recv_pack->data.send_fd, message, sizeof(MESSAGE), 0) < 0) {
        my_err("send", __LINE__);
    }
    
    pthread_mutex_unlock(&mutex);
    return 0;
}

int del_message(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[100];

    pthread_mutex_lock(&mutex);
    sprintf(need, "update chat_messages set send_can_look = 0 where send_user = %d and recv_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    memset(need, 0, sizeof(need));
    sprintf(need, "update chat_messages set recv_can_look = 0 where recv_user = %d and send_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    memset(need, 0, sizeof(need));
    sprintf(need, "delete from chat_messages where send_can_look = 0 and recv_can_look = 0");
    mysql_query(&mysql, need);

    return 0;
}

int send_gmes(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    MYSQL_RES       *result, *result1;
    MYSQL_ROW       row, row1;
    char            need[100];
    BOX             *tmp = box_head;

    pthread_mutex_lock(&mutex);
    recv_pack->type = RECV_GMES;
    sprintf(need, "select *from groups where group_account = %d", recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "select *from group_members where group_account = %d", recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    while (row = mysql_fetch_row(result)) {
        if (atoi(row[2]) == recv_pack->data.send_account) {
            continue;
        }
        memset(need, 0, sizeof(need));
        sprintf(need, "select *from user_data where account = %d", atoi(row[2]));
        mysql_query(&mysql, need);
        result1 = mysql_store_result(&mysql);
        row1 = mysql_fetch_row(result1);
        if (atoi(row1[3]) == 1) {
            if (send(atoi(row1[4]), recv_pack, sizeof(PACK), 0) < 0) {
                my_err("send", __LINE__);
            }
        } else {
            while (tmp != NULL) {
                if (tmp->recv_account == atoi(row1[0])) {
                    break;
                }
                tmp = tmp->next;
            }
           /* tmp->send_account1[tmp->number] = recv_pack->data.send_account;
            tmp->group_account[tmp->number] = recv_pack->data.send_account;
            strcpy(tmp->message[tmp->number++], recv_pack->data.read_buff);
            if (send(atoi(row1[4]), recv_pack, sizeof(PACK), 0) < 0) {
                my_err("send", __LINE__);
            }*/
            if (tmp == NULL) {
                tmp = (BOX *)malloc(sizeof(BOX));
                tmp->number = 0;
                tmp->recv_account = atoi(row1[0]);
                tmp->send_account1[tmp->number] = recv_pack->data.send_account;
                tmp->group_account[tmp->number] = recv_pack->data.recv_account;
                strcpy(tmp->message[tmp->number++], recv_pack->data.read_buff);
                if (box_head == NULL) {
                    box_head = box_tail = tmp;
                    box_tail->next = NULL;
                } else {
                    box_tail->next = tmp;
                    box_tail = tmp;
                    box_tail->next = NULL;
                }
            } else {
                tmp->send_account1[tmp->number] = recv_pack->data.send_account;
                tmp->group_account[tmp->number] = recv_pack->data.send_account;
                strcpy(tmp->message[tmp->number++], recv_pack->data.read_buff);
            }
        }
    }
    recv_pack->type = SEND_GMES;
    pthread_mutex_unlock(&mutex);

    return 0;
}

/*int send_file(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[100];
    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from friends where user = %d and friend_user = %d", recv_pack->data.send_account, recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    memset(need, 0, sizeof(need));
    sprintf(need, "select *from user_data where account = %d", recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (atoi(row[3]) == 0) {
        pthread_mutex_unlock(&mutex);
        return -1;
    } else {
        recv_pack->data.recv_fd = atoi(row[4]);
        recv_pack->type = RECV_FILE;
        if (send(recv_pack->data.recv_fd, recv_pack, sizeof(PACK), 0) < 0) {
            my_err("send", __LINE__);
        }
        recv_pack->type = SEND_FILE;
        pthread_mutex_unlock(&mutex);
        return 0;
    }
}
int read_file(PACK *pack, MYSQL mysql1) {
    PACK            *recv_pack = pack;
    MYSQL           mysql = mysql1;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[100];
    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from user_data where account = %d", recv_pack->data.recv_account);
    printf("^^%s\n", need);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    recv_pack->data.recv_fd = atoi(row[4]);
    recv_pack->type = SEND_F;
    if (send(recv_pack->data.recv_fd, recv_pack, sizeof(PACK), 0) < 0) {
        my_err("send", __LINE__);
    }
    recv_pack->type = OK_FILE;
    if (send(recv_pack->data.send_fd, recv_pack, sizeof(PACK), 0) < 0) {
        my_err("send", __LINE__);
    }
    pthread_mutex_unlock(&mutex);
    
    return 0;
}*/

int ok_file(PACK *pack, MYSQL mysql1) {
    MYSQL           mysql = mysql1;
    PACK            *recv_pack = pack;
    MYSQL_RES       *result;
    MYSQL_ROW       row;
    char            need[100];
    
    pthread_mutex_lock(&mutex);
    sprintf(need, "select *from user_data where account = %d", recv_pack->data.recv_account);
    mysql_query(&mysql, need);
    result = mysql_store_result(&mysql);
    row = mysql_fetch_row(result);
    if (!row) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    if (atoi(row[3]) == 0) {
        pthread_mutex_unlock(&mutex);
        return -1;
    }
    recv_pack->data.recv_fd = atoi(row[4]);
    recv_pack->type = RECV_FILE; 
    if (send(recv_pack->data.recv_fd, recv_pack, sizeof(PACK), 0) < 0) {
        my_err("send", __LINE__);
    }
    recv_pack->type = OK_FILE;
    if (send(recv_pack->data.send_fd, recv_pack, sizeof(PACK), 0) < 0) {
        my_err("send", __LINE__);
    }
    pthread_mutex_unlock(&mutex);
    
    return 0;
}

以上就是聊天室的全部代码,后续持续推出讲解…

发布了35 篇原创文章 · 获赞 82 · 访问量 7540

猜你喜欢

转载自blog.csdn.net/qq_44049351/article/details/100178261