自写聊天室_LinuxC实现(3)——客户端模块化优化及流程图

这里,我对客户端代码进行了模块化优化,并优化了界面,加上了注释


流程图:




模块化划分:

共分为一下几个模块:

mian.cpp :

socket启动及链接,开启线程

logic.cpp

功能函数:对应了登陆与注册,私聊,群聊,文件传输,好友和群组管理函数


tools.cpp

工具函数:求文件大小,发送包,和一些判断函数

view.cpp

显示的界面函数:菜单显示函数,聊天界面函数,信息查看函数

client.h

        结构体声明,函数声明,全局变量声明


下面是客户端的界面截图
登陆界面:


主界面:



好友查看界面:


聊天界面:


文件发送界面:



文件接收界面:



文件消息盒子界面:


聊天记录界面:



下面上代码(已加详细注释):

main.cpp

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

/*****************same with server**********************/
#define LOGIN                    1
#define REGISTER                 2
#define FRIEND_SEE               3
#define FRIEND_ADD               4
#define FRIEND_DEL               5
#define GROUP_SEE                6  
#define GROUP_CREATE             7
#define GROUP_JOIN               8
#define GROUP_QIUT               9
#define GROUP_DEL                10
#define CHAT_ONE                 11
#define CHAT_MANY                12
#define FILE_SEND_BEGIN          13
#define FILE_SEND_BEGIN_RP       14
#define FILE_SEND_STOP_RP        15
#define FILE_RECV_RE             16
#define FILE_SEND                17
#define FILE_RECV_BEGIN          18 
#define FILE_RECV_BEGIN_RP       19
#define FILE_RECV_STOP_RP        20
#define FILE_RECV                21
#define FILE_FINI_RP             22
#define MES_RECORD               23
#define EXIT                     -1


#define SIZE_PASS_NAME   10
#define MAX_PACK_CONTIAN 100
#define MAX_CHAR         300
#define NUM_MAX_DIGIT    10

#define DOWNLINE   0
#define ONLINE     1
#define BUZY       2



/**************************************************/

typedef struct  friend_info
{
    int statu;
    int mes_num;
    char name[MAX_CHAR];
}FRIEND_INFO; 




typedef struct user_infor{
    char        username    [MAX_CHAR];
    FRIEND_INFO friends     [MAX_CHAR];
    int         friends_num;
    char        group       [MAX_CHAR][MAX_CHAR];
    int         group_num;
}USER_INFOR;






/******************be sure same with server*******************************/
typedef struct datas{
    char    send_name[MAX_CHAR];
    char    recv_name[MAX_CHAR];
    int     send_fd;
    int     recv_fd;
    //time_t  time;
    char    mes[MAX_CHAR*2];
}DATA;

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

typedef struct pthread_parameter
{
    int a;
    int b;
}PTHREAD_PAR;



typedef struct prinit_mes
{
    char name[MAX_CHAR];
    char time[MAX_CHAR];
    char mes [MAX_CHAR];
    
}PRINT_MES;

typedef struct sockaddr SA;




void init();
void *deal_statu(void *arg);
void *clien_recv_thread(void *arg);
void init_clien_pthread();
int main_menu();






int send_login(char username_t[],char password_t[]);
int login();
int send_registe(char username_t[],char password_t[]);
void registe();
void get_status_mes();
void change_statu(PACK pack_deal_statu_t);
void add_friend();
void del_friend();
void group_create();
void group_join();
void group_qiut();
void group_del();
void send_mes_to_one();
void send_mes_to_group();
void send_mes(char mes_recv_name[],int type);
void *show_mes(void *username);
void print_mes(int id);
void send_file();
void *pthread_send_file(void *mes_t);
void send_file_send(int begin_location,char *file_path);
int file_mes_box();
void deal_file_mes(int id);
void mes_sendfile_fail(int id);
void mes_recv_requir(int id);
void mes_recvfile_fail(int id);
void *pthread_recv_file(void *par_t);
int mes_record();
void print_mes_record(PACK* pack_t);



int login_menu();
void show_mes_smart(char *name  ,char *mes);
void friends_see();
void group_see();
void print_main_menu();


void my_err(const char * err_string,int line);
void sig_close(int i);
int get_file_size(char *file_name);
void file_infor_delete(int id);
int judge_same_group(char *group_name);
int judge_same_friend(char add_friend_t[]);
int get_choice(char *choice_t);
void send_pack(int type,char *send_name,char *recv_name,char *mes);
void send_pack_memcpy(int type,char *send_name,char *recv_name,char *mes);








USER_INFOR m_my_infor;

/*****************send*********************/
PACK m_pack_send   [MAX_CHAR];
int  m_send_num;


/*****************recv*********************/
PACK m_pack_recv_friend_see   [MAX_PACK_CONTIAN];
PACK m_pack_recv_chat         [MAX_PACK_CONTIAN];
PACK m_pack_recv_send_file    [MAX_PACK_CONTIAN];
PACK m_pack_recv_file_mes     [MAX_PACK_CONTIAN];
PACK m_pack_recv_file         [MAX_PACK_CONTIAN];

int m_recv_num_friend_see;
int m_recv_num_chat;
int m_recv_num_send_file;
int m_recv_num_file_mes;
int m_recv_num_file;
int m_print_mes_flag;

/****************************************************/

int m_flag_group_create;
int m_flag_group_join ;
int m_flag_group_del  ;
int m_flag_print_mes;
int m_flag_print_recorde;
// int window_col;
// int window_row;
/****************************************************/

PRINT_MES m_print_mes[10];
int m_print_mes_num;
/***********************function***********************/
int sockfd;
char *IP = "115.159.205.168";
short PORT = 11112;
typedef struct sockaddr SA;
pthread_mutex_t  mutex_local_user;
pthread_mutex_t  mutex_recv_file;



void init()
{
	printf("客户端开始启动\n");
    sockfd = socket(AF_INET,SOCK_STREAM,0);//启动socket
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = inet_addr(IP);
    if(connect(sockfd,(SA*)&addr,sizeof(addr))==-1){
        perror("无法连接到服务器");
        printf("客户端启动失败\n");
        exit(-1);
    }
    printf("客户端启动成功\n");
}


/***************************
 * 根据发来数据包及时更新
 * 好友状态
 * *************************/

void *deal_statu(void *arg)
{
    int i;
    while(1)
    {
        pthread_mutex_lock(&mutex_local_user); 
        for(i=1;i<=m_recv_num_friend_see;i++)
        {
            //printf("flag1\n");
            change_statu(m_pack_recv_friend_see[i]);
        }
        m_recv_num_friend_see = 0;
        pthread_mutex_unlock(&mutex_local_user); 
        usleep(1); 
    }
}


/***************************
 * 一直接收客户端发来的包
 * 并把包存储到数组当中
 * *************************/

void *clien_recv_thread(void *arg)
{
    int i;
    PACK pack_t;
    pthread_t pid_send_file;
    while(1)
    {
        if(recv(sockfd,&pack_t,sizeof(PACK),0) < 0){
            my_err("recv",__LINE__);
        }
        //for(int i=1;i <= )
        pthread_mutex_lock(&mutex_local_user); 
        
        for(int i=1 ;i<= m_my_infor.friends_num;i++)
        {
            if(strcmp(m_my_infor.friends[i].name,pack_t.data.send_name) == 0)
            {
                m_my_infor.friends[i].mes_num++;
                break;
            }
        }

        switch(pack_t.type)
        {
            case FRIEND_SEE:
                m_pack_recv_friend_see[++m_recv_num_friend_see] = pack_t;
                break;
            case GROUP_CREATE:
                m_flag_group_create = pack_t.data.mes[0];
                break;
            case GROUP_JOIN:
                m_flag_group_join   = pack_t.data.mes[0];
                break;
            case GROUP_DEL:
                m_flag_group_del    = pack_t.data.mes[0];
            case CHAT_ONE:
                m_pack_recv_chat[++m_recv_num_chat]             = pack_t;
                break;
            case CHAT_MANY:
                m_pack_recv_chat[++m_recv_num_chat]             = pack_t;
                break;
            //case SEND_FILE:
              //  m_pack_recv_send_file[++m_recv_num_send_file]   = pack_t;
                //break;
            case FILE_SEND_BEGIN_RP:
                 pthread_create(&pid_send_file,NULL,pthread_send_file,(void *)pack_t.data.mes);
                break; 
            case FILE_SEND_STOP_RP:
                m_pack_recv_file_mes[++m_recv_num_file_mes]             = pack_t;
                break;
            case FILE_RECV_BEGIN:
                m_pack_recv_file_mes[++m_recv_num_file_mes]             = pack_t;
                break;
            case FILE_RECV:
                pthread_mutex_lock(&mutex_recv_file); 
                m_pack_recv_file[++m_recv_num_file]                     = pack_t;                
                
                pthread_mutex_unlock(&mutex_recv_file);

                break; 
            case FILE_RECV_STOP_RP:
                m_pack_recv_file_mes[++m_recv_num_file_mes]             = pack_t;
                break;
            case MES_RECORD:
                PACK *pack_record = (PACK *)malloc(sizeof(PACK));
                memcpy(pack_record,&pack_t,sizeof(PACK));
                print_mes_record(pack_record);
                break;
        }
        pthread_mutex_unlock(&mutex_local_user); 
        usleep(1); 
    }
}


//开启线程
void init_clien_pthread()
{
    pthread_t pid_deal_statu,pid_recv,pid_recv_file;
    pthread_create(&pid_deal_statu,NULL,deal_statu,NULL);
    pthread_create(&pid_recv,NULL,clien_recv_thread,NULL);
} 


//主菜单
int main_menu()
{
    char choice_t[100];
    int chioce;
    do
    {
        get_status_mes();
        //printf("pack num_chat:%d\n", m_recv_num_chat);
        print_main_menu();
        scanf("%s",choice_t);
        chioce = get_choice(choice_t);
        switch(chioce)
        {  
            case 1:
                friends_see();
                break;
            case 2:
                add_friend();
                break;
            case 3:
                del_friend();
                break;
            case 4:
                group_see();
                break;
            case 5:
                group_create();
                break;
            case 6:
                group_join();
                break;
            case 7:
                group_qiut();
                break;
            case 8:
                group_del();
                break;
            case 9:
                send_mes_to_one();
                break;
            case 10:
                send_mes_to_group();
                break;
            case 11:
                send_file();
                break;
            case 12:
                file_mes_box();
                break;
            case 13:
                mes_record();
            default:
                break;
        }
    }while(chioce!=0);
    return 0;
}



int main(int argc, char const *argv[])
{
	int flag =0;
    // struct winsize size;  
	
    signal(SIGINT,sig_close);//关闭CTRL+C
    init();//启动并连接服务器
    
    // ioctl(STDIN_FILENO,TIOCGWINSZ,&size); //get size of window
    // window_col = size.ws_col;
    // window_row = size.ws_row;
   
    if(login_menu() == 0)//判断是否登陆成功  
        return 0;   
    init_clien_pthread();//开启线程
    main_menu();        //主菜单
	return 0;
}

/^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/
logic.cpp
#include "client.h"





/*
* 向服务端发送登陆信息
*/

int send_login(char username_t[],char password_t[])
{
    PACK recv_login_t;
    int login_judge_flag = 0;
    send_pack(LOGIN,username_t,"server",password_t);
     
    if(recv(sockfd,&recv_login_t,sizeof(PACK),0) < 0){
        my_err("recv",__LINE__);
    }
    login_judge_flag = recv_login_t.data.mes[0] - 48;
    return login_judge_flag;
}

/*
* 根据输入信息向客户端发送登陆请求
* 并根据返回内容,提示用户
*/
int login()
{
    int flag = 0;
    
    int login_flag = 0;
    char username_t [MAX_CHAR];
    char password_t [MAX_CHAR];
    printf("please input the username:\n");
    scanf("%s",username_t);
    printf("please input the password\n");
    scanf("%s",password_t);

    login_flag = send_login(username_t,password_t);
    if(login_flag ==  2){
        printf("\033[;31mthe username is not exit.\033[0m\n");
        return 0;
    }   
    if(login_flag ==  3 ){
        printf("\033[;31mthe user has loged in .\033[0m\n");
        return 0;
    }  
    if(login_flag == 0) {
        printf("\033[;31mthe password is not crrect.\033[0m\n");
        return 0;
    }
    strcpy(m_my_infor.username,username_t);
    printf("\033[;32mload successfully!\033[0m\n");
    return 1;
}








/*
* 向服务端发送注册信息
*/
int send_registe(char username_t[],char password_t[])
{
    PACK recv_registe_t;
    int send_registe_flag;
    
    send_pack(REGISTER,username_t,"server",password_t);
    
    if(recv(sockfd,&recv_registe_t,sizeof(PACK),0) < 0){
        my_err("recv",__LINE__);
    }
    send_registe_flag = recv_registe_t.data.mes[0] - 48;
    return send_registe_flag;
}

/*
* 根据输入信息向客户端发送注册请求
* 并根据返回内容,提示用户
*/
void registe()
{
    int flag = 0;
    flag = REGISTER;
    char username_t[MAX_CHAR];
    char password_t[MAX_CHAR];

   
    
    printf("please input the username you want register:\n");
    scanf("%s",username_t);
    printf("please input the password you want register:\n");
    scanf("%s",password_t);
    if(send_registe(username_t,password_t))
        printf("\033[;32mregiste successfully!\033[0m\n");
    else 
        printf("\033[;31mthe name is used ,please input another one\033[0m\n");
}  



/*
 * 向服务端请求更新好友状态
*/
void get_status_mes()
{
    PACK pack_friend_see;
    pack_friend_see.type = FRIEND_SEE;
    strcpy(pack_friend_see.data.send_name,m_my_infor.username);
    strcpy(pack_friend_see.data.recv_name,"server");
    memset(pack_friend_see.data.mes,0,sizeof(pack_friend_see.data.mes));
    if(send(sockfd,&pack_friend_see,sizeof(PACK),0) < 0){
        my_err("send",__LINE__);
    }
}

//根据服务端发送来的包,利用字符串解析,更新当前好友状态
void change_statu(PACK pack_deal_statu_t)
{
    int count = 0;
    m_my_infor.friends_num=pack_deal_statu_t.data.mes[count++];
    //更新好友信息
    for(int i=1; i <= m_my_infor.friends_num ;i++)
    {
        for(int j=0;j<SIZE_PASS_NAME;j++)
        {
            if(j == 0)   
                m_my_infor.friends[i].statu = pack_deal_statu_t.data.mes[count+j] - 48;
            else
                m_my_infor.friends[i].name[j-1] = pack_deal_statu_t.data.mes[count+j];
        }
        count += SIZE_PASS_NAME;
    }
    //更新群组信息
    m_my_infor.group_num=pack_deal_statu_t.data.mes[count++];
    for(int i=1 ;i <= m_my_infor.group_num ;i++)
    {
        for(int j=0;j<SIZE_PASS_NAME;j++)
        {
            m_my_infor.group[i][j] = pack_deal_statu_t.data.mes[count+j];
        }
        count += SIZE_PASS_NAME;
    }
}


/**************************************/





//添加好友
void add_friend()
{
    char add_friend_t[MAX_CHAR];
    
    printf("please input the name of friend you want to add:\n");
    scanf("%s",add_friend_t);
    if(strcmp(add_friend_t,m_my_infor.username) == 0)
    {
        printf("you can't add youself to be your friend!\n");
        return;
    }
    //判断是否已经添加过该好友
    if(judge_same_friend(add_friend_t))
    {
        printf("you already have same friends!\n");
        return ;
    }
    printf("m_my_infor.username:%s\n", m_my_infor.username);
    send_pack(FRIEND_ADD,m_my_infor.username,"server",add_friend_t);
    get_status_mes();
}



//删除好友
void del_friend()
{
    char del_friend_t[MAX_CHAR];
    printf("please input the name of friend you want to delete:\n");
    scanf("%s",del_friend_t);
    //判断是否添加过该好友
    if(!judge_same_friend(del_friend_t))
    {
        printf("you don't have this friends on list!\n");
        return ;
    }
    printf("m_my_infor.username:%s\n", m_my_infor.username);
    //发送包
    send_pack(FRIEND_DEL,m_my_infor.username,"server",del_friend_t);
    //得到状态信息
    get_status_mes();
}








//创建群组
void group_create()
{
    char group_name[MAX_CHAR];
    printf("please input the group name you want to create:\n");
    scanf("%s",group_name);
    send_pack(GROUP_CREATE,m_my_infor.username,"server",group_name);
    while(!m_flag_group_create);
    printf("m_flag_group_create=%d\n", m_flag_group_create);
    if(m_flag_group_create == 2) 
        printf("create group successfully!\n");
    else if(m_flag_group_create == 1)
        printf("this group has been created!\n");
    m_flag_group_create = 0;
}


//加入群组
void group_join()
{

    char group_name[MAX_CHAR];
    printf("please input the group name you want to join:\n");
    scanf("%s",group_name);
    //判断是否已经加入该群
    for(int i=1;i <= m_my_infor.group_num ;i++)
    {
        if(strcmp(m_my_infor.group[i],group_name) == 0)
        {
            printf("you have join this group!\n");
            return ;
        }
    }

    send_pack(GROUP_JOIN,m_my_infor.username,"server",group_name);
    while(!m_flag_group_join);
    if(m_flag_group_join == 2) 
        printf("join group successfully!\n");
    else if(m_flag_group_join == 1)
        printf("there is no group named %s\n",group_name);
    m_flag_group_join = 0;
}

//退出群组
void group_qiut()
{
    char group_name[MAX_CHAR];
    printf("please input the group name you want to qiut:\n");
    scanf("%s",group_name);
    //判断是否添加过该群组
    for(int i=1;i <= m_my_infor.group_num ;i++)
    {
        if(strcmp(m_my_infor.group[i],group_name) == 0)
        {
            send_pack(GROUP_QIUT,m_my_infor.username,"server",group_name);
            printf("quit group %s successfully!\n",group_name);
            return ;
        }
    }
    
    printf("you did't join this group!\n");
}

//解散群
void group_del()
{
    char group_name[MAX_CHAR];
    printf("please input the group name you want to delete:\n");
    scanf("%s",group_name);
    for(int i=1;i <= m_my_infor.group_num ;i++)
    {
        if(strcmp(m_my_infor.group[i],group_name) == 0)
        {
            send_pack(GROUP_DEL,m_my_infor.username,"server",group_name);
            while(!m_flag_group_del);
            printf("m_flag_group_del=%d\n", m_flag_group_del);
            if(m_flag_group_del == 2) 
                printf("delete group successfully!\n");
            else if(m_flag_group_del == 1)
                printf("you isn't the owner of group %s\n",group_name);
            return ;
        }
    }
    
    printf("you did't join this group!\n");
}





















/*************************************************/

//私聊
void send_mes_to_one()
{
    pthread_t pid;
    int id;
    char mes_recv_name[MAX_CHAR];
    friends_see();//print friend list !

    printf("please input the name you want to chat\n");
    scanf("%s",mes_recv_name);
    if (!(id=judge_same_friend(mes_recv_name)))
    {
        printf("sorry,you don't have the friend named !%s\n",mes_recv_name);
        return ;
    }
    printf("\33[2J \33[1;1H\033[;33m\33[1m-^-^-^-^-^-^-^-^-^-^-message-^-^-^-^-^-^-^-^-^-^-\033[0m");
    printf("\33[26B\n");
    m_flag_print_mes = 1;
    m_my_infor.friends[id].mes_num = 0;
    //开启线程显示信息
    pthread_create(&pid,NULL,show_mes,(void *)mes_recv_name);
    send_mes(mes_recv_name,CHAT_ONE);
}

//群聊
void send_mes_to_group()
{
    pthread_t pid;
    char mes_recv_group_name[MAX_CHAR];
    group_see();
    printf("please input the group you want to chat\n");
    scanf("%s",mes_recv_group_name);
    if (!judge_same_group(mes_recv_group_name))
    {
        printf("sorry,you don't have the group named !%s\n",mes_recv_group_name);
        return ;
    }

    m_flag_print_mes = 1;
    printf("\33[2J \33[1;1H\033[;33m\33[1m-^-^-^-^-^-^-^-^-^-^-message-^-^-^-^-^-^-^-^-^-^-\033[0m");
    printf("\33[26B\n");
    //开启线程显示信息
    pthread_create(&pid,NULL,show_mes,(void *)mes_recv_group_name);
    send_mes(mes_recv_group_name,CHAT_MANY);
}


//接收用户输入并发送信息到客户端
void send_mes(char mes_recv_name[],int type)
{
    PACK pack_send_mes;
    char mes[MAX_CHAR];
    time_t timep;
    getchar();
    printf("\033[;34m\33[1m-^-^-^-^-^-^-^-^-^-^-please input-^-^-^-^-^-^-^-^-^-^-\033[0m\n");
    while(1)
    {   
        time(&timep);
        memset(mes,0,sizeof(mes));
        printf("\33[s");
        fflush(stdout);
        //if(type == CHAT_ONE)
            // printf("%s->",m_my_infor.username);
        fgets(mes,MAX_CHAR,stdin);
        while(mes[0] == 10)
        {
            printf("\33[1A");
            fflush(stdout);
            fgets(mes,MAX_CHAR,stdin);
        }

        //当用户输入quit时退出
        if(strcmp(mes,"quit\n") == 0)
            break;
        printf("\33[u");
        fflush(stdout);
        printf("\33[s");
        fflush(stdout);
        printf("\33[K\n\33[K\n\33[K\n");
        fflush(stdout);
        printf("\33[u");
        fflush(stdout);

        //输入的的同时,输出信息
        show_mes_smart(m_my_infor.username ,mes);
        
        //printf("\t%s\n%s\n", m_my_infor.username,ctime(&timep),mes);
        //发送给客户端
        send_pack(type,m_my_infor.username,mes_recv_name,mes);
    }
    m_flag_print_mes = EXIT;
}

/*
 * 在聊天的同时启动,启动线程读取,存储区域的
 * 消息,并显示出来
*/
void *show_mes(void *username)
{
    int id;
    char *user_name = (char *)username;
    while(1)
    {
        //如果退出聊天,就不再显示
        if (m_flag_print_mes == EXIT)
            break;
        pthread_mutex_lock(&mutex_local_user); 
        id = 0;

        //检索信息
        for(int i = 1 ;i <= m_recv_num_chat; i++)
        {
            if(strcmp(m_pack_recv_chat[i].data.send_name,user_name) == 0)
            {
                id = i;

                //输出信息
                print_mes(id);
                m_recv_num_chat--;
                for(int j = id; j <= m_recv_num_chat&&m_recv_num_chat ;j++)
                {
                    m_pack_recv_chat[j]  =  m_pack_recv_chat[j+1];
                }
                break;
            }
        }
        
        pthread_mutex_unlock(&mutex_local_user); 
        usleep(1);    
    }
}

//根据寻找到的包把信息输出
void print_mes(int id)
{
    char group_print_name[MAX_CHAR];
    memset(group_print_name,0,sizeof(group_print_name));
    if(m_pack_recv_chat[id].type == CHAT_ONE)
    {
        show_mes_smart(m_pack_recv_chat[id].data.send_name,m_pack_recv_chat[id].data.mes);
    }
    else
    {
        for(int i=0;i<SIZE_PASS_NAME;i++)
        {
            group_print_name[i] = m_pack_recv_chat[id].data.mes[i];
        }
        show_mes_smart( group_print_name,m_pack_recv_chat[id].data.mes+SIZE_PASS_NAME);
    }
}



/*******************************************/







/*
 * 向服务端请求发送文件,并将文件的大小
 * 发送给服务端
*/

void send_file()
{
    char  recv_name[MAX_CHAR];
    char  file_path[MAX_CHAR];
    int   file_size_t;
    char  mes_t[MAX_CHAR];
    friends_see();
    printf("please input the friend name:\n");
    scanf("%s",recv_name);

    int id = judge_same_friend(recv_name);
    if(id == 0)
    {
        printf("you don't hava this friend!\n");
        return ;
    }
    printf("please input the path of file you want to send :\n");
    scanf("%s",file_path);
    
    //得到文件的大小
    file_size_t = get_file_size(file_path);
    printf("file_size :%d\n", file_size_t);

    if(file_size_t == 0)
    {
        printf("please input creact file path\n");
        return ;
    }
    //字符串分析
    int digit = 0;
    while(file_size_t != 0)
    {   
        mes_t[digit++] = file_size_t%10;
        file_size_t /= 10;
    }
    mes_t[digit]  = -1;
   
    for(int i=0 ;i< SIZE_PASS_NAME ;i++)
    {
        mes_t[NUM_MAX_DIGIT+i] = file_path[i];
    }
    //发送请求
    send_pack_memcpy(FILE_SEND_BEGIN,m_my_infor.username,recv_name,mes_t);
}



//当接收到允许发送的消息时,开启线程发送文件
void *pthread_send_file(void *mes_t)
{
    char *mes = (char *)mes_t;
    int begin_location = 0;
    char file_name[MAX_CHAR];
    printf("\033[;31m \nfunction:pthread_send_file\033[0m \n");
    //解析到服务端已接收文件大小
    for(int i=0 ;i<NUM_MAX_DIGIT ;i++)
    {
        if(mes[i] == -1)  
            break;
        int t1 = 1;
        for(int l=0;l<i;l++)
            t1*=10;
        begin_location += (int)mes[i]*t1;

    }
    strcpy(file_name,mes+NUM_MAX_DIGIT);
    send_file_send(begin_location,file_name);
}


//从起始位置向服务端发送文件
void send_file_send(int begin_location,char *file_path)
{
    int fd;
    int length;
    int file_size;
    int sum = begin_location;
    char mes[MAX_CHAR*2];
    printf("\33[2J\33[1;1H\n");
    printf("\033[;34m\33[1m^-^-^-^-^-^-^-^-^-^happychat^-^-^-^-^-^-^-^-^-^\033[0m\n");
    printf("\n\nsending the file.........\n");
    
    //打开文件
    if((fd = open(file_path,O_RDONLY)) == -1)
    {
        my_err("open",__LINE__);
        return ;
    }
    file_size=lseek(fd, 0, SEEK_END);
    
    printf("file_size=%d",file_size);
    //文件内部指针移动
    lseek(fd ,begin_location ,SEEK_SET);

    bzero(mes, MAX_CHAR*2); 

    // 每读取一段数据,便将其发送给客户端,循环直到文件读完为止 
    while((length = read(fd  ,mes+NUM_MAX_DIGIT ,MAX_CHAR*2 - NUM_MAX_DIGIT)) > 0) 
    {
        sum += length;
      //  printf("length = %d\n", length);
        int digit = 0;
        while(length != 0)
        {   
            mes[digit++] = length%10;
            length /= 10;
        }
        mes[digit]  = -1;
        int color;
        int jindu=(int)((double)sum/file_size*100);
        printf("have sended :");
        for(int i = 0 ;i<jindu/10;i++)
        {
            color = i%6;
            printf("\033[;%dm\33[1m=\033[0m",color+32);
            fflush(stdout);
        }
        printf("\033[;31m\33[1m>\033[0m");
        fflush(stdout);
        for(int j = 0;j<10-jindu/10;j++)
        {
            printf(" ");
            fflush(stdout);
        }
        printf("\033[;31m\33[1m|\033[0m %d%%    %d  \n",jindu,sum);
        
        send_pack_memcpy(FILE_SEND,m_my_infor.username,file_path,mes);
        
        if(sum == file_size)  
            break;
        bzero(mes, MAX_CHAR*2); 
        usleep(100000);
        printf("\33[1A\33[K");
        fflush(stdout);
    } 
    // 关闭文件 
    close(fd);
    printf("send finished!!\n");
    print_main_menu();
}









/*
 * 显示文件处理消息,并根据提供选择
*/

int file_mes_box()
{
    char choice_t[100];
    int chioce;
    do
    {
        get_status_mes();
        printf("\033[;34m\33[1m^-^-^-^-^-^-^-^-^-^file mes box^-^-^-^-^-^-^-^-^-^\033[0m\n");
        for(int i = 1; i <= m_recv_num_file_mes;i++)
        {
            if(m_pack_recv_file_mes[i].type == FILE_SEND_STOP_RP)
                printf("\t\033[;34m\33[1m*\033[0m   \033[;31m\33[1msend file %s filed\033[0m       \n",m_pack_recv_file_mes[i].data.send_name);
            if(m_pack_recv_file_mes[i].type == FILE_RECV_BEGIN)
                printf("\t\033[;34m\33[1m*\033[0m   \033[;33m\33[1m%s send file %s to you\033[0m   \n", m_pack_recv_file_mes[i].data.send_name,m_pack_recv_file_mes[i].data.mes+SIZE_PASS_NAME);
            if(m_pack_recv_file_mes[i].type == FILE_RECV_STOP_RP)
                printf("\t\033[;34m\33[1m*\033[0m   \033[;31m\33[1mrecv file %s filed\033[0m       \n", m_pack_recv_file_mes[i].data.mes+NUM_MAX_DIGIT);
        }
                printf("\t\033[;34m\33[1m*\033[0m             0.exit                               \n");
        printf("\033[;34m\33[1m^-^-^-^-^-^-^-^-^-^end^-^-^-^-^-^-^-^-^-^-^-^-^-^-\033[0m\n");
        printf("\t\tchoice:");
        scanf("%s",choice_t);
        chioce = get_choice(choice_t);
        //进行处理
        if(chioce != -1)   
            deal_file_mes(chioce);

    }while(chioce!=0);
    return 0;
}




//对文件信息进行分类处理
void deal_file_mes(int id)
{
    if(m_pack_recv_file_mes[id].type == FILE_SEND_STOP_RP)
    {
        mes_sendfile_fail(id);
    }
    else if(m_pack_recv_file_mes[id].type == FILE_RECV_BEGIN)
    {
        mes_recv_requir(id);
    }else if(m_pack_recv_file_mes[id].type == FILE_RECV_STOP_RP)
    {
        mes_recvfile_fail(id);
    }
}


//处理文件上传失败,并询问是否重发
//进行断点续传
void mes_sendfile_fail(int id)
{
    char chioce[10];
    //解析已经上传的字节数
    int begin_location = 0;
    for(int i=0 ;i<NUM_MAX_DIGIT ;i++)
    {
        if( m_pack_recv_file_mes[id].data.mes[i] == -1)  
            break;
        printf("%d\n\n",m_pack_recv_file_mes[id].data.mes[i]);
        int t1 = 1;
        for(int l=0;l<i;l++)
            t1*=10;
        begin_location += (int)m_pack_recv_file_mes[id].data.mes[i] * t1;

    }


    //询问是否重传
    int file_size_t = get_file_size(m_pack_recv_file_mes[id].data.send_name);
    printf("\033[;31m\33[1mthe file %s send failed ,have sended \033[;32m%d%%\033[;31m,do you want send again?\033[0m\n", m_pack_recv_file_mes[id].data.send_name,(int)((double)begin_location/file_size_t*100));
    printf("y/n :");
    scanf("%s",chioce);
    

    if(chioce[0] != 'Y' && chioce[0] != 'y')
    {
        file_infor_delete(id);
        return ;
    }
    
    //进行重传
    send_file_send(begin_location,m_pack_recv_file_mes[id].data.send_name);
    file_infor_delete(id);
}

//处理下载文件请求,询问是否接收文件
void mes_recv_requir(int id)
{
    pthread_t  pid_recv_file;
    char choice[10];
    int len ;
    int fd;
    char mes_t[MAX_CHAR];
    int file_size = 0;
    char file_name[SIZE_PASS_NAME];
    
    PTHREAD_PAR * par_t = (PTHREAD_PAR *)malloc(sizeof(PTHREAD_PAR));
    //解析文件大小
    for(int i=0 ;i<NUM_MAX_DIGIT ;i++)
    {
        if(m_pack_recv_file_mes[id].data.mes[i] == -1)  
            break;
        int t1 = 1;
        for(int l=0;l<i;l++)
            t1*=10;
        file_size += (int)m_pack_recv_file_mes[id].data.mes[i]*t1;

    }   
    // for(int i=0 ;i<=50;i++)
        // printf("%d\n", m_pack_recv_file_mes[id].data.mes[i]);
    // printf("%s\n", m_pack_recv_file_mes[id].data.mes+NUM_MAX_DIGIT);
    strcpy(file_name,m_pack_recv_file_mes[id].data.mes+NUM_MAX_DIGIT);

    
    printf("\033[;33m\33[1m %s send file %s size(%db)to you \033[0m\n", m_pack_recv_file_mes[id].data.send_name,file_name,file_size);
    printf(" do you want receive it? \n");
    printf("(y/n) :");
    scanf("%s", choice);
    if(choice[0] != 'Y' && choice[0] != 'y')
    {
        file_infor_delete(id);
        return ;
    }


    //建立文件
    if((fd = open(file_name,O_WRONLY | O_CREAT , S_IRUSR | S_IWUSR)) < 0)
    {
        my_err("open",__LINE__);
        return ;
    }
    len = lseek(fd, 0, SEEK_END);
    close(fd);

    par_t->a = file_size;
    par_t->b = len;
    
    int digit = 0;
    while(len != 0)
    {   
        mes_t[digit++] = len%10;
        len /= 10;
    }
    mes_t[digit]  = -1;
    //发送同意同意
    send_pack_memcpy(FILE_SEND_BEGIN_RP ,m_my_infor.username ,file_name ,mes_t);
    //开启线程接收文件
    pthread_create(&pid_recv_file,NULL,pthread_recv_file,(void *)par_t);

    file_infor_delete(id);
}

//处理接收文件中断信息,
//并询问是否继续接收
void mes_recvfile_fail(int id)
{
    pthread_t  pid_recv_file;
    char chioce[10];
    int begin_location_server;
    int file_size;
    char file_name[SIZE_PASS_NAME];
    char mes_t[MAX_CHAR];
    PTHREAD_PAR * par_t = (PTHREAD_PAR *)malloc(sizeof(PTHREAD_PAR));
    //解析已经接收的字节数
    for(int i=0 ;i<NUM_MAX_DIGIT ;i++)
    {
        if(m_pack_recv_file_mes[id].data.mes[i] == -1)  
            break;
        int t1 = 1;
        for(int l=0;l<i;l++)
            t1*=10;
        file_size += (int)m_pack_recv_file_mes[id].data.mes[i]*t1;

    }   

    strcpy(file_name,m_pack_recv_file_mes[id].data.mes+NUM_MAX_DIGIT);
    
    begin_location_server= get_file_size(file_name);
    

    par_t->a = file_size;
    par_t->b = begin_location_server;
    printf("\033[;31m\33[1mthe file %s recv failed ,have recved \033[;32m%d%%\033[;31m,do you want recv continue?\033[0m\n", file_name,(int)((double)begin_location_server/file_size*100));
    printf("y/n :");
    scanf("%s",chioce);
    
    

    if(chioce[0] != 'Y' && chioce[0] != 'y')
    {
        file_infor_delete(id); 
        return ;
    }


    int len = begin_location_server;
    int digit = 0;
    while(len != 0)
    {   
        mes_t[digit++] = len%10;
        len /= 10;
    }
    mes_t[digit]  = -1;

    //返回同意信息
    send_pack_memcpy(FILE_SEND_BEGIN_RP ,m_my_infor.username ,file_name ,mes_t);
    //开启线程接收文件
    pthread_create(&pid_recv_file,NULL,pthread_recv_file,(void *)par_t);

    file_infor_delete(id);
}

//接收文件线程,
//从存储接收包的地方检索到信息
//并写入文件
//当文件写入完成,关闭线程
void *pthread_recv_file(void *par_t)
{
    PTHREAD_PAR * pthread_par  = (PTHREAD_PAR * )par_t;
    int file_size              = pthread_par->a ;
    int begin_location_server  = pthread_par->b;
    int sum                    = begin_location_server; 
    while(1)
    {
        pthread_mutex_lock(&mutex_recv_file); 
        int  fd;
        char file_name[MAX_CHAR];
        for(int i=1;i<=m_recv_num_file ;i++)
        {
            
            int  len = 0;
            for(int j=0 ;j<NUM_MAX_DIGIT ;j++)
            {
                if(m_pack_recv_file[i].data.mes[j] == -1)  
                    break;
                int t1 = 1;
                for(int l=0;l<j;l++)
                    t1*=10;
                len += (int)m_pack_recv_file[i].data.mes[j]*t1;

            }

            strcpy(file_name,m_pack_recv_file[i].data.send_name);
            //you can creat this file when you get the file_send_begin
            if((fd = open(file_name,O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)) < 0)
            {
                my_err("open",__LINE__);
                return NULL;
            }

            if(write(fd,m_pack_recv_file[i].data.mes + NUM_MAX_DIGIT,len) < 0)
                my_err("write",__LINE__);
            // 关闭文件 
            close(fd);
            sum += len;
            int color;
            int jindu=(int)((double)sum/file_size*100);
            printf("have recved :");
            for(int i = 0 ;i<jindu/10;i++)
            {
                color = i%6;
                printf("\033[;%dm\33[1m=\033[0m",color+32);
                fflush(stdout);
            }
            printf("\033[;31m\33[1m>\033[0m");
            fflush(stdout);
            for(int j = 0;j<10-jindu/10;j++)
            {
                printf(" ");
                fflush(stdout);
            }
            printf("\033[;31m\33[1m|\033[0m %d%%    %d  \n",jindu,sum);
            
            m_recv_num_file = 0;
            //文件接收完成,输出提示信息,跳出线程
            if(sum >= file_size)  
            {
                send_pack(FILE_FINI_RP,m_my_infor.username,"server",file_name);
                printf("send finished!!\n");
                print_main_menu();
                return NULL;  
            }
        }

        pthread_mutex_unlock(&mutex_recv_file);
        usleep(10);
    }   
}







//显示历史信息
//向服务端发送请求消息
int mes_record()
{
    char username[MAX_CHAR];
    printf("please input the username that you want see:\n");
    scanf("%s",username);
    printf("the recording :\n");
    send_pack(MES_RECORD,m_my_infor.username,"server",username);
    printf("\33[2J\33[20A\033[;33m\33[1m^-^-^-^-^-^-^-^-^message recordes^-^-^-^-^-^-^-^\033[0m\n");
    while(!m_flag_print_recorde) ;
    printf("printf recordes finished!!\n");
    m_flag_print_recorde = 0;
    return 0;
}



//输出历史消息
void print_mes_record(PACK* pack_t)
{
    if(strcmp(pack_t->data.send_name , "server") == 0)
    {
        if(strcmp(pack_t->data.mes,m_my_infor.username) == 0)
        {    
            printf("\033[;34m\33[1m%s\033[0m\t\033[;34m\033[0m\n",pack_t->data.mes);
            printf("%s\n", pack_t->data.mes+SIZE_PASS_NAME);
        }
        else
        {
            printf("\033[;33m\33[1m%s\033[0m\t\033[;33m\033[0m\n",pack_t->data.mes);
            printf("%s\n", pack_t->data.mes+SIZE_PASS_NAME);
        }
        
    }
    else 
        m_flag_print_recorde = 1;    
    free(pack_t);
}

/*****************************************/




/*void print_file_mes()
{
    for(int i=1 ;i<=5;i++)
    {
        printf("hahahahahaha*****\n");
        printf("%s\n", m_pack_recv_file_mes[i].data.send_name);
        printf("%s",m_pack_recv_file_mes[i].data.recv_name);
        for(int j=0;j<=5;j++)
            printf("%d\n\n",m_pack_recv_file_mes[i].data.mes[j]);

    }
}*/

/^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/
tools.cpp
#include "client.h"





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

void sig_close(int i)
{
    //关闭客户端的描述符
    close(sockfd);
    exit(0);
}

/*you need creat the file before!*/
//得到文件大小
int get_file_size(char *file_name)
{
    int fd;
    int len;
    if((fd = open(file_name,O_RDONLY)) == -1)
    {
        my_err("open",__LINE__);
        return 0;
    }
    len = lseek(fd, 0, SEEK_END);
    close(fd);
    return len;
}

//从文件数组中删除文件信息
void file_infor_delete(int id)
{
    pthread_mutex_lock(&mutex_local_user); 
    for(int j = id ;j <=m_recv_num_file_mes ;j++)
    {
        m_pack_recv_file_mes[j]  = m_pack_recv_file_mes[j+1];
    }
    m_recv_num_file_mes--;
    pthread_mutex_unlock(&mutex_local_user); 
}



//判断是否有重复的组
int judge_same_group(char *group_name)
{
    int i;
    for(i=1;i<=m_my_infor.group_num;i++)
    {
        if(strcmp(m_my_infor.group[i],group_name) == 0)
            return 1;
    }
    return 0;
}



//判断是否有重复的好友
int judge_same_friend(char add_friend_t[])
{
    int i;
    for(i=1;i<=m_my_infor.friends_num;i++)
    {
        if(strcmp(m_my_infor.friends[i].name,add_friend_t) == 0)
            return i;
    }
    return 0;
}

//为避免输入时出现的意外错误,进行字符串解析
int get_choice(char *choice_t)
{
    int choice =0;
    for(int i=0;i<strlen(choice_t) ;i++)
        if(choice_t[i]<'0' || choice_t[i]>'9')
            return -1;
    for(int i=0;i<strlen(choice_t);i++)
    {
        int t=1;
        for(int j=1;j<strlen(choice_t)-i;j++)
        {
            t *=10;
        }
        choice += t*(int)(choice_t[i] - 48);
    }
    return choice;
}

//根据参数信息发送包
void send_pack(int type,char *send_name,char *recv_name,char *mes)
{
    PACK pack_send_pack;
    time_t timep;
    pack_send_pack.type = type;
    strcpy(pack_send_pack.data.send_name,send_name);
    strcpy(pack_send_pack.data.recv_name,recv_name);
    strcpy(pack_send_pack.data.mes,mes); 
    time(&timep);
    //pack_send_pack.data.time = timep;
    if(send(sockfd,&pack_send_pack,sizeof(PACK),0) < 0){
        my_err("send",__LINE__);
    }
}


//根据参数信息发送包
void send_pack_memcpy(int type,char *send_name,char *recv_name,char *mes)
{
    PACK pack_send_pack;
    time_t timep;
    pack_send_pack.type = type;
    strcpy(pack_send_pack.data.send_name,send_name);
    strcpy(pack_send_pack.data.recv_name,recv_name);
    memcpy(pack_send_pack.data.mes,mes,MAX_CHAR*2); 
    time(&timep);
   // pack_send_pack.data.time = timep;
    if(send(sockfd,&pack_send_pack,sizeof(PACK),0) < 0){
        my_err("send",__LINE__);
    }
}


/^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/
view.cpp

#include "client.h"



//登陆菜单
int login_menu()
{
    char choice_t[100];
    int chioce;
    do
    {
        printf("\n\t\t\033[;34m\33[1m*******************************\033[0m\n");
        printf("\t\t\033[;34m\33[1m*\033[0m        1.login in           \033[;34m\33[1m*\033[0m \n");
        printf("\t\t\033[;34m\33[1m*\033[0m        2.register           \033[;34m\33[1m*\033[0m \n");
        printf("\t\t\033[;34m\33[1m*\033[0m        0.exit               \033[;34m\33[1m*\033[0m \n");
        printf("\t\t\033[;34m\33[1m*******************************\033[0m\n");
        printf("\t\tchoice:");
        scanf("%s",choice_t);
        chioce = get_choice(choice_t);
        switch(chioce)
        {  
            case 1:
                if(login() == 1)
                    return 1;
                break;
            case 2:
                registe();
                break;
            default:
                break;
        }
    }while(chioce!=0);
    return 0;
}






//显示聊天信息
void show_mes_smart(char *name  ,char *mes)
{
    time_t timep;
    int number = 6;
    char time1[100];
    int len ; 
    time (&timep);
    strcpy(time1,ctime(&timep));
    len = strlen(time1);
    time1[len-5] = '\0'; 
    

    if(m_print_mes_num == number)  
    {
        for(int i=1;i<=5 ;i++)
            m_print_mes[i] = m_print_mes[i+1];
        strcpy(m_print_mes[number].name,name);
       // strcpy(m_print_mes[number].time,time);
        strcpy(m_print_mes[number].mes,mes);
    }
    else{
         strcpy(m_print_mes[++m_print_mes_num].name,name);
         //strcpy(m_print_mes[m_print_mes_num].time,time);
         strcpy(m_print_mes[m_print_mes_num].mes,mes);
    }


    printf("\33[s");
    fflush(stdout);

    printf("\33[25A\n");  
    
    for(int i=1;i<=20;i++)
        printf("\33[K\n");
    printf("\33[21A\n");

    for(int i=1;i<=m_print_mes_num;i++)
    {
        if(strcmp(m_print_mes[i].name,m_my_infor.username) == 0)
        {
            printf("\033[;34m\33[1m%s\033[0m\t\033[;34m%s\033[0m\n",m_print_mes[i].name,time1+10);
            printf("%s\n", m_print_mes[i].mes);
        }
        else
        {
            printf("\033[;33m\33[1m%s\033[0m\t\033[;33m%s\033[0m\n",m_print_mes[i].name,time1+10);
            printf("%s\n", m_print_mes[i].mes);
        }
        

    }
    for(int i=1;i<=6- m_print_mes_num ;i++)
    {
        printf("\n");
        printf("\n\n");

    }

    printf("\33[u");
    fflush(stdout);
}




//好友列表查看
void friends_see()
{
   
    pthread_mutex_lock(&mutex_local_user);
    printf("\33[2J\n");
    printf("\33[1;1H\n");
    printf("\033[;35m\33[1m\t  ***********the list of friends************* \033[0m \n");
    for(int i=1 ;i<=m_my_infor.friends_num ;i++)
    {
        switch(m_my_infor.friends[i].statu)
        {
           case ONLINE:
                printf("\033[;35m\33[1m\t  ID[%d]:  \033[0m     \033[;32m\33[1m%s\033[0m [ONLINE] ", i,m_my_infor.friends[i].name);
                if(m_my_infor.friends[i].mes_num)
                    printf("\033[;33m%d messages\033[0m\n", m_my_infor.friends[i].mes_num);
                else 
                    printf("\n");
                break;
           case DOWNLINE:
                printf("\033[;35m\33[1m\t  ID[%d]:  \033[0m     \033[;31m\33[1m%s\033[0m [DOWNLINE] ", i,m_my_infor.friends[i].name);
                if(m_my_infor.friends[i].mes_num)
                    printf("\033[;33m%d messages\033[0m\n", m_my_infor.friends[i].mes_num);
                else 
                    printf("\n");
                break;
        }
    }
    printf("\n\n");
    printf("\033[;35m\33[1m\t  *******************end********************* \033[0m \n");
    pthread_mutex_unlock(&mutex_local_user);  
}




//群组信息查看
void group_see()
{
    pthread_mutex_lock(&mutex_local_user); 
    printf("\33[2J\n");
    printf("\33[1;1H\n");
    printf("\033[;35m\33[1m\t  ***********the list of groups************* \033[0m \n");
    for(int i=1 ;i<=m_my_infor.group_num ;i++)
    {
        printf("\033[;35m\33[1m\t  ID[%d]:  \033[0m     \033[;32m\33[1m%s\033[0m", i,m_my_infor.group[i]);
    }
    printf("\n\n");
    printf("\033[;35m\33[1m\t  ********************end******************* \033[0m \n");
    pthread_mutex_unlock(&mutex_local_user);  
}




void print_main_menu()
{
    printf("\n\t\t\033[;34m\33[1m*********************************\033[0m \n");
    printf("\t\t\033[;34m\33[1m*\033[0m        1.show   friends       \033[;34m\33[1m*\033[0m\n");
    printf("\t\t*        2.add    friends       *\n");
    printf("\t\t\033[;34m\33[1m*\033[0m        3.delete friends       \033[;34m\33[1m*\033[0m\n");
    printf("\t\t\033[;34m\33[1m*\033[0m        4.show   group         \033[;34m\33[1m*\033[0m\n");
    printf("\t\t*        5.create group         *\n");
    printf("\t\t\033[;34m\33[1m*\033[0m        6.join   group         \033[;34m\33[1m*\033[0m\n");
    printf("\t\t\033[;34m\33[1m*\033[0m        7.quit   group         \033[;34m\33[1m*\033[0m\n");
    printf("\t\t*        8.delete group         *\n");
    printf("\t\t\033[;34m\33[1m*\033[0m        9.chat with one        \033[;34m\33[1m*\033[0m\n");
    printf("\t\t\033[;34m\33[1m*\033[0m        10.chat with many      \033[;34m\33[1m*\033[0m\n");
    printf("\t\t*        11.send  file          *\n");
    printf("\t\t\033[;34m\33[1m*\033[0m        12.file message box %d  \033[;34m\33[1m*\033[0m\n",m_recv_num_file_mes);
    printf("\t\t\033[;34m\33[1m*\033[0m        13.mes recording       \033[;34m\33[1m*\033[0m\n");
    printf("\t\t\033[;34m\33[1m*\033[0m        0.exit                 \033[;34m\33[1m*\033[0m\n");
    printf("\t\t\033[;34m\33[1m*********************************\033[0m\n");
    printf("\t\tchoice:");
}


/^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/
client.cpp
#include <mysql/mysql.h> 
#include <gtk/gtk.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <termios.h>  

/*****************same with server**********************/
#define LOGIN                    1
#define REGISTER                 2
#define FRIEND_SEE               3
#define FRIEND_ADD               4
#define FRIEND_DEL               5
#define GROUP_SEE                6  
#define GROUP_CREATE             7
#define GROUP_JOIN               8
#define GROUP_QIUT               9
#define GROUP_DEL                10
#define CHAT_ONE                 11
#define CHAT_MANY                12
#define FILE_SEND_BEGIN          13
#define FILE_SEND_BEGIN_RP       14
#define FILE_SEND_STOP_RP        15
#define FILE_RECV_RE             16
#define FILE_SEND                17
#define FILE_RECV_BEGIN          18 
#define FILE_RECV_BEGIN_RP       19
#define FILE_RECV_STOP_RP        20
#define FILE_RECV                21
#define FILE_FINI_RP             22
#define MES_RECORD               23
#define EXIT                     -1


#define SIZE_PASS_NAME   10
#define MAX_PACK_CONTIAN 100
#define MAX_CHAR         300
#define NUM_MAX_DIGIT    10

#define DOWNLINE   0
#define ONLINE     1
#define BUZY       2



/**************************************************/

typedef struct  friend_info
{
    int statu;
    int mes_num;
    char name[MAX_CHAR];
}FRIEND_INFO; 




typedef struct user_infor{
    char        username    [MAX_CHAR];
    FRIEND_INFO friends     [MAX_CHAR];
    int         friends_num;
    char        group       [MAX_CHAR][MAX_CHAR];
    int         group_num;
}USER_INFOR;








/******************be sure same with server*******************************/
typedef struct datas{
    char    send_name[MAX_CHAR];
    char    recv_name[MAX_CHAR];
    int     send_fd;
    int     recv_fd;
    //time_t  time;
    char    mes[MAX_CHAR*2];
}DATA;

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

typedef struct pthread_parameter
{
    int a;
    int b;
}PTHREAD_PAR;



typedef struct prinit_mes
{
    char name[MAX_CHAR];
    char time[MAX_CHAR];
    char mes [MAX_CHAR];
    
}PRINT_MES;

typedef struct sockaddr SA;



void init();
void *deal_statu(void *arg);
void *clien_recv_thread(void *arg);
void init_clien_pthread();
int main_menu();




int send_login(char username_t[],char password_t[]);
int login();
int send_registe(char username_t[],char password_t[]);
void registe();
void get_status_mes();
void change_statu(PACK pack_deal_statu_t);
void add_friend();
void del_friend();
void group_create();
void group_join();
void group_qiut();
void group_del();
void send_mes_to_one();
void send_mes_to_group();
void send_mes(char mes_recv_name[],int type);
void *show_mes(void *username);
void print_mes(int id);
void send_file();
void *pthread_send_file(void *mes_t);
void send_file_send(int begin_location,char *file_path);
int file_mes_box();
void deal_file_mes(int id);
void mes_sendfile_fail(int id);
void mes_recv_requir(int id);
void mes_recvfile_fail(int id);
void *pthread_recv_file(void *par_t);
int mes_record();
void print_mes_record(PACK* pack_t);



int login_menu();
void show_mes_smart(char *name  ,char *mes);
void friends_see();
void group_see();
void print_main_menu();


void my_err(const char * err_string,int line);
void sig_close(int i);
int get_file_size(char *file_name);
void file_infor_delete(int id);
int judge_same_group(char *group_name);
int judge_same_friend(char add_friend_t[]);
int get_choice(char *choice_t);
void send_pack(int type,char *send_name,char *recv_name,char *mes);
void send_pack_memcpy(int type,char *send_name,char *recv_name,char *mes);




extern USER_INFOR m_my_infor;

extern PACK m_pack_send   [MAX_CHAR];
extern int  m_send_num;


/*****************recv*********************/
extern PACK m_pack_recv_friend_see   [MAX_PACK_CONTIAN];
extern PACK m_pack_recv_chat         [MAX_PACK_CONTIAN];
extern PACK m_pack_recv_send_file    [MAX_PACK_CONTIAN];
extern PACK m_pack_recv_file_mes     [MAX_PACK_CONTIAN];
extern PACK m_pack_recv_file         [MAX_PACK_CONTIAN];

extern int m_recv_num_friend_see;
extern int m_recv_num_chat;
extern int m_recv_num_send_file;
extern int m_recv_num_file_mes;
extern int m_recv_num_file;
extern int m_print_mes_flag;

/****************************************************/

extern int m_flag_group_create;
extern int m_flag_group_join ;
extern int m_flag_group_del  ;
extern int m_flag_print_mes;
extern int m_flag_print_recorde;
// int window_col;
// int window_row;
/****************************************************/

extern PRINT_MES m_print_mes[10];
extern int m_print_mes_num;
/***********************function***********************/
extern int sockfd;
extern char *IP ;
extern short PORT ;

extern pthread_mutex_t  mutex_local_user;
extern pthread_mutex_t  mutex_recv_file;



/^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/
Makefile
CC=g++ -std=c++11
OBJ = happychat_client
all:
	$(CC)  -o  $(OBJ)  -cpp   ./*.cpp    `pkg-config  --libs --cflags gtk+-2.0` -pthread -g
#	$(CC)  -o $(OBJ)  ./*.o -I `pkg-config --libs --cflags gtk+-2.0` -pthread -g
#	rm -rf *.o

clean:
	-rm -rf *.o


/^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^/





  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值