用TCP实现简易版聊天室

用TCP实现简易版聊天室

TCP相较于UDP和select有着传输稳定的优点。
介于之前用select已经实现过,所以本程序只有注册,登录,忘记密码,私聊,群聊,注销,退出等功能
当然,tcp也是可以实现之前能用select实现的所有功能。
废话不多说,上代码:


头文件

#ifndef _CHAT_H_
#define _CHAT_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sqlite3.h>

#define PORT    8888

#define FAILURE 10000
#define SUCCESS 10001
#define ERROR1  10002
#define ERROR2  10003
#define RIGHT   10004


#define SIGN    1   //注册
#define LOGO    2   //登陆
#define FORGET  3   //忘记密码
#define QUIT    4   //退出
#define SHOW    5   //显示用户
#define PCHAT   6   //私聊
#define GCHAT   7   //群聊
#define BACK    8   //注销
#define CQUIT   9   //客户端退出
#define SHOWNUM 10  //显示在线人数


struct communication
{
    int idnumber;                       //帐号
    char password[20];                  //密码
    int sex;                            //性别    0 m 1 f
    char telephone[20];                 //手机号
    char nickname[20];                  //昵称
    int time_sr;                        //收发消息时间
    char message[100];                  //消息
    int num;                            //在线人数
    char Fromnickname[20];              //发消息人的昵称
    int ToFd;                           //目的地 0表示和服务器通信
    int flag;                           //宏标志
    int endflag;                        //结束标志位
};
typedef struct communication commu;


struct status
{
    int idnumber;                       //帐号
    char nickname[20];                  //昵称
    int  usersockfd;                    //用户fd
    struct status *next;
};
typedef struct status Status;
typedef Status * STATUS;

/*********************************************服务器***********************************/
void *server_receive(void *arg);
void server_sign(commu RecvBuf, int aim);
int compare(void *para, int columnCount, char **columnValue, char **columnName);
void server_logo(commu RecvBuf, int aim);
int compare1(void *para, int columnCount, char **columnValue, char **columnName);
void server_forget(commu RecvBuf, int aim);

void server_show(commu RecvBuf, int aim);
void server_pchat(commu RecvBuf, int aim);
void server_gchat(commu RecvBuf, int aim);

/*********************************************客户端***********************************/
void show_welcome();
void show_sign();
void sign_in(int sockfd);
void show_logo();
void logo_in(int sockfd);
void show_forget();
void forget_password(int sockfd);
void client_quit(int sockfd);

void show_in();
void show_quit();
void delay();

void show_menu();

void *client_menu(void *arg);
void private_chat(void *arg);
void show_people(int sockfd);
void *Send(void *arg);
void *Recv(void *arg);
void group_chat(int sockfd);
void client_back(int sockfd);
void client_cquit();

#endif

服务器

#include "chat.c"

sqlite3 *ppdb;
STATUS sta;
char sql[200] = {0};



int main()
{
    int fd[100] = {0};
/*********************************************初始化用户链表***************************************/

    sta = (STATUS)malloc(sizeof(Status));
    sta->next = NULL;

/***********************************************打开数据库*************************************/

    int ret;

    ret = sqlite3_open("infor.db", &ppdb);
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_open");
        exit(1);
    }

    sprintf(sql, "create table if not exists infor (idnumber integer primary key, password text, nickname text, sex interger, telephone text);");
    ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_exec");
        exit(1);
    }


/************************************************线程通信************************************************/

    int length, i = 0;
    int sockfd;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    pthread_t tid[100] = {0};

    sockfd = socket(PF_INET, SOCK_STREAM, 0);
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }

    int opt = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = PF_INET;
    server_addr.sin_port = PORT;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if(-1 == ret)
    {
        perror("bind");
        exit(1);
    }

    printf("等待链接...\n");
    ret = listen(sockfd, 20);
    if(-1 == ret)
    {
        perror("listen");
        exit(1);
    }

    while(1)
    {
        length = sizeof(client_addr);
        fd[i] = accept(sockfd, (struct sockaddr*)&client_addr, &length);
        if(-1 == fd[i])
        {
            perror("accept");
            exit(1);
        }

        printf("第%d号用户,端口号:%d\n", fd[i], client_addr.sin_port);

        ret = pthread_create(&tid[i], NULL, server_receive, (void *)&fd[i]);
        if(0 != ret)
        {
            perror("pthread_create");
            exit(1);
        }
        i++;
    }

    close(sockfd);

    return 0;
}

客户端

#include "chat.c"

int fflag = 0;              //跳出登录界面
pthread_t tid[2] = {0};

int main()
{
    fflag = 0;

/*********************************************链接服务器***************************************/
    int sockfd, ret;
    struct sockaddr_in server_addr;
    sockfd = socket(PF_INET, SOCK_STREAM, 0); 
    if(-1 == sockfd)
    {

        perror("socket");
        exit(1);
    }   

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = PF_INET;
    server_addr.sin_port = PORT;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    printf("正在连接服务器...\n");
    ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if(-1 == ret)
    {                                                  
        perror("connect");
        exit(1);
    }


/**********************************************登录界面选择********************************************/

    char choice[10] = {0};
    while(1)
    {
//      system("clear");
        show_welcome();
        scanf("%s", choice);
        switch (atoi(&choice[0]))
        {
            case 1:
                logo_in(sockfd);
                if(fflag == 1)
                {
                    show_in();
//                  sleep(2);
                    ret = pthread_create(&tid[0], NULL, client_menu, (void *)&sockfd);
                    if(0 != ret)
                    {
                        perror("pthread_create1");
                        exit(1);
                    }   
                    ret = pthread_create(&tid[1], NULL, Recv, (void *)&sockfd);
                    if(0 != ret)
                    {
                         perror("pthread_create2");
                         exit(1);
                    }       
                    pthread_join(tid[0], NULL);
                    pthread_join(tid[1], NULL);
                }

                break;
            case 2:
                sign_in(sockfd);
                break;  
            case 3:
                forget_password(sockfd);
                break;
            case 4:
                client_quit(sockfd);
                break;
            default:
                printf("请重输:\n");
                break;
        }

        if(fflag == 2)
        {
            show_quit();
            return 0;
        }
    }
    return 0;
}

服务器接口

#include "chat.c"

extern sqlite3 *ppdb;
extern STATUS sta;
extern char sql[200];

int aim_a = 0;
int count = 0;
char name[20];

/***********************************************注册用户,写入数据库中********************************************/

void server_sign(commu RecvBuf, int aim)
{
    printf("第%d号用户:注册!\n", aim);                                            //
    int ret;
    aim_a = aim;
    memset(&sql, 0, sizeof(sql));               //注意要取地址
    sprintf(sql, "insert into infor (idnumber, password, nickname, sex, telephone) values (%d, '%s', '%s', %d, '%s');", RecvBuf.idnumber, RecvBuf.password, RecvBuf.nickname, RecvBuf.sex, RecvBuf.telephone);
//  printf("id:%d passwd:%s nickname:%s sex:%d telephone:%s\n", RecvBuf.idnumber, RecvBuf.password, RecvBuf.nickname, RecvBuf.sex, RecvBuf.telephone);                                                                       //
    ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
    if(ret != SQLITE_OK)
    {
        memset(&RecvBuf, 0, sizeof(RecvBuf));
        RecvBuf.flag = ERROR1;
//      printf("flag4:%d\n", RecvBuf.flag);                                     //
        ret = send(aim, &RecvBuf, sizeof(RecvBuf), 0);
        if(-1 == ret)
        {
            perror("send");
            exit(1);
        }
        return;
    }
    else 
    {
        memset(&RecvBuf, 0, sizeof(RecvBuf));
        RecvBuf.flag = RIGHT;
//      printf("flag5:%d\n", RecvBuf.flag);                                     //
        ret = send(aim, &RecvBuf, sizeof(RecvBuf), 0);
        if(-1 == ret)
        {
            perror("send");
            exit(1);
        }
        return;
    }
}

/**********************************************登录用户,登录成功加入链表中****************************************/

void server_logo(commu RecvBuf, int aim)
{
    commu SendBuf;
    count = 0;
    printf("第%d号用户:登录!\n", aim);                                                    //
    printf("id:%d passwd:%s\n", RecvBuf.idnumber, RecvBuf.password);                    //
    int ret;
    aim_a = aim;
    memset(&sql, 0, sizeof(sql));
    sprintf(sql ,"select * from infor;");
    ret = sqlite3_exec(ppdb, sql, compare, (void *)&RecvBuf, NULL);
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_exec");
        exit(1);
    }

    if(1 == count)
    {
        STATUS tmp  = sta;
        STATUS p = sta->next;
        while(p)
        {
            if(p->idnumber == RecvBuf.idnumber)
            {
                memset(&RecvBuf, 0, sizeof(RecvBuf));
                RecvBuf.flag = FAILURE;                                         //用户已在线
                ret = send(aim, &RecvBuf, sizeof(RecvBuf), 0);
                if(-1 == ret)
                {
                    perror("send");
                    exit(1);
                }
                return;
            }
            tmp = p;
            p = p->next;
        }
        memset(&SendBuf, 0, sizeof(SendBuf));
        SendBuf.flag = RIGHT;                                                   //登录成功
        ret = send(aim, &SendBuf, sizeof(SendBuf), 0);
        if(-1 == ret)
        {
            perror("send");
            exit(1);
        }

        STATUS n = (STATUS)malloc(sizeof(Status));
        if(NULL == n)
        {
            perror("malloc");
            exit;
        }
        n->idnumber = RecvBuf.idnumber;
        strcpy(n->nickname, name);
        n->usersockfd = aim;
        tmp->next = n;
        n->next = NULL;
        return;
    }
    else if(2 == count)
    {
        return;
    }
    memset(&RecvBuf, 0, sizeof(RecvBuf));
    RecvBuf.flag = ERROR1;                                                      //数据库空,用户没注册    
    ret = send(aim, &RecvBuf, sizeof(RecvBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }
    return;
}

int compare(void *para, int columnCount, char **columnValue, char **columnName)
{
    commu RecvBuf;
    int ret;
    int j;
    for(j = 0; j < columnCount; j++)
    {
        if((*(((int **)columnValue)[0]) - 48) == ((*(commu *)para).idnumber))
        {
            if(!strcmp(columnValue[1], ((*(commu *)para).password)))
            {
                memset(name, 0, sizeof(name));
                strcpy(name, columnValue[2]);
                count = 1;
                return 0;
            }
            else
            {
                memset(&RecvBuf, 0, sizeof(RecvBuf));
                RecvBuf.flag = ERROR2;                                              //帐号密码错误
                ret = send(aim_a, &RecvBuf, sizeof(RecvBuf), 0);
                if(-1 == ret)
                {
                    perror("send");
                    exit(1);
                }
                count = 2;
                return 0;
            }
        }
    }   

    return 0;
}

/********************************************忘记密码****************************************************/

void server_forget(commu RecvBuf, int aim)
{
    printf("第%d号用户:找回密码!\n", aim);
    printf("id:%d, nickname:%s, sex:%d, telephone:%s\n", RecvBuf.idnumber, RecvBuf.nickname, RecvBuf.sex, RecvBuf.telephone);
    count = 0;
    commu SendBuf;
    int ret;
    aim_a = aim;
    memset(&sql, 0, sizeof(sql));   
    sprintf(sql ,"select * from infor;");
    ret = sqlite3_exec(ppdb, sql, compare1, (void *)&RecvBuf, NULL);
    if(ret != SQLITE_OK)
    {
        perror("sqlite3_exec");
        exit(1);
    }

    if(3 == count)
    {
        return;
    }

    memset(&SendBuf, 0, sizeof(SendBuf));
    SendBuf.flag = ERROR1;                                                          //没有该用户,返回错误
    ret = send(aim, &SendBuf, sizeof(SendBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

    return;
}

int compare1(void *para, int columnCount, char **columnValue, char **columnName)
{
    commu RecvBuf;
    commu SendBuf;
    int ret;
    int j;
    char pswd[20];
    for(j = 0; j < columnCount; j++)
    {
        memset(pswd, 0, sizeof(pswd));
        strcpy(pswd, columnValue[1]);
        printf("pswd:%s\n", pswd);

        printf("columnValue[1]:%s\n", columnValue[1]);
        if(((*(columnValue[0]) - 48) == (*(commu *)para).idnumber) && (!strcmp(columnValue[2], ((*(commu *)para).nickname))) && ((*(columnValue[3]) - 48) == (*(commu *)para).sex) && (!strcmp(columnValue[4], ((*(commu *)para).telephone))))
        {
            STATUS p = sta->next;
            while(p)
            {
                if(p->idnumber == (*(commu *)para).idnumber)
                {
                    memset(&RecvBuf, 0, sizeof(RecvBuf));
                    RecvBuf.flag = FAILURE;                                     //用户已在线,返回失败
                    ret = send(aim_a, &RecvBuf, sizeof(RecvBuf), 0);
                    if(-1 == ret)
                    {
                        perror("send");
                        exit(1);
                    }
                    count = 3;      
                    return 0;   
                }
                p = p->next;
            }
            printf("jinglema?\n");

            memset(&SendBuf, 0, sizeof(SendBuf));                               //用户不在线,返回正确
            SendBuf.flag = RIGHT;
            strcpy(SendBuf.password, pswd);
            printf("sf1:%d\n",SendBuf.flag);
            printf("Sendpswd:%s\n", SendBuf.password);
            ret = send(aim_a, &SendBuf, sizeof(SendBuf), 0);
            if(-1 == ret)
            {
                perror("send");
                exit(1);
            }
            count = 3;
            return 0;
        }
    }   
    return 0;
}

/********************************************显示当前在线人数*********************************************/

void server_show(commu RecvBuf, int aim)
{
    commu SendBuf;
    int ret, i = 0, j = 0;
    STATUS p = sta->next;

    while(p)
    {
        i++;
        p = p->next;
    }

    memset(&SendBuf, 0, sizeof(SendBuf));
    SendBuf.num = i;
    SendBuf.flag = SHOWNUM;
    ret = send(aim, &SendBuf, sizeof(SendBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

    p = sta->next;
    for(j; j < i-1; j++)
    {
        memset(&SendBuf, 0, sizeof(SendBuf));
        SendBuf.flag = SHOW;
        strcpy(SendBuf.nickname, p->nickname);
        ret = send(aim, &SendBuf, sizeof(SendBuf), 0);
        if(-1 == ret)
        {
            perror("send");
            exit(1);
        }
        p = p->next;
    }

    memset(&SendBuf, 0, sizeof(SendBuf));
    SendBuf.flag = SHOW;
    SendBuf.endflag = 1;
    strcpy(SendBuf.nickname, p->nickname);
    ret = send(aim,&SendBuf, sizeof(SendBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

        p = p->next;

    return;
}

/********************************************私聊*********************************************************/

void server_pchat(commu RecvBuf, int aim)
{
    int ret;
    aim_a = 0;
    STATUS p;
    p = sta->next;
    while(p)
    {
        if(!strcmp(RecvBuf.nickname, p->nickname))
        {
            aim_a = p->usersockfd;      
        }
        p = p->next;
    }
    p = sta->next;
    if(0 == aim_a)
    {
        commu SendBuf;
        memset(&SendBuf, 0, sizeof(SendBuf));
        SendBuf.flag = FAILURE;
        strcpy(SendBuf.nickname, RecvBuf.nickname);
        ret = send(aim , &SendBuf, sizeof(SendBuf), 0);
        if(-1 == ret)
        {
            perror("send");
            exit(1);
        }
    }
    else
    {
        while(p)
        {
            if(p->usersockfd == aim)
            {
                strcpy(RecvBuf.Fromnickname, p->nickname);
                ret = send(aim_a, &RecvBuf, sizeof(RecvBuf), 0);
                if(-1 == ret)
                {
                    perror("send");
                    exit(1);
                }
            }
            p = p->next;
        }
    }
    return;
}

/*********************************************群发********************************************************/

void server_gchat(commu RecvBuf, int aim)
{
    aim_a = 0;
    int ret;
    STATUS p;
    p = sta->next;
    while(p)
    {
        if(aim == p->usersockfd)
        {
            strcpy(RecvBuf.Fromnickname, p->nickname);
        }

        p = p->next;
    }

    p = sta->next;
    while(p)
    {
        if(aim != p->usersockfd)
        {
            aim_a = p->usersockfd;
            ret = send(aim_a, &RecvBuf, sizeof(RecvBuf), 0);
            if(-1 == ret)
            {
                perror("send");
                exit(1);
            }
        }

        p = p->next;
    }
    if(0 == aim_a)
    {
        commu SendBuf;
        memset(&SendBuf, 0, sizeof(SendBuf));
        SendBuf.flag = ERROR1;
        ret = send(aim, &SendBuf, sizeof(SendBuf), 0);
        if(-1 == ret)
        {
            perror("send");
            exit(1);
        }
    }

    return;
}

/*************************************************注销****************************************************/

void server_back(commu RecvBuf, int aim)
{
    int ret;
    STATUS tmp = sta;
    STATUS p = sta->next;
    while(p)
    {
        if(aim == p->usersockfd)
        {
            if(p->next == NULL)
            {
                tmp->next = NULL;
                free(p);
            }
            else
            {
                tmp->next = p->next;
                free(p);
                p->next = NULL;
            }
        }
        tmp = p;
        p = p->next;
    }
    return;
}

/****************************************************CQUIT************************************************/

void server_cquit(commu RecvBuf, int aim)
{
    int ret;
    STATUS tmp = sta;
    STATUS p = sta->next;
    while(p)
    {
        if(aim == p->usersockfd)
        {
            if(p->next == NULL)
            {
                tmp->next = NULL;
                free(p);
            }
            else
            {
                tmp->next = p->next;
                free(p);
                p->next = NULL;
            }
        }
        tmp = p;
        p = p->next;
    }
    return;

}

/********************************************服务器依据flag处理客户端消息*********************************/

void *server_receive(void *arg)
{
    commu RecvBuf;
    int ret, ffflag = 0;

    pthread_detach(pthread_self());

    while(1)
    {
        memset(&RecvBuf, 0, sizeof(RecvBuf));

        ret = recv(*(int *)arg, &RecvBuf, sizeof(RecvBuf), 0);
        if(-1 == ret)
        {
            perror("recv");
            exit(1);
        }

        printf("flag3:%d\n", RecvBuf.flag);                                                     //
        printf("id:%d passwd:%s\n", RecvBuf.idnumber, RecvBuf.password);                        //

        switch (RecvBuf.flag)
        {
            case LOGO:
                server_logo(RecvBuf, *(int *)arg);
                break;
            case SIGN:
                server_sign(RecvBuf, *(int *)arg);
                break;
            case FORGET:
                server_forget(RecvBuf, *(int *)arg);
                break;
            case QUIT:
                ffflag = 1;
                break;
            case SHOW:
                server_show(RecvBuf, *(int *)arg);
                break;
            case PCHAT:
                server_pchat(RecvBuf, *(int *)arg);
                break;
            case GCHAT:
                server_gchat(RecvBuf, *(int *)arg);
                break;
            case BACK:
                server_back(RecvBuf, *(int *)arg);
                break;
            case CQUIT:
                server_cquit(RecvBuf, *(int *)arg);
                ffflag = 1;
                break;
            default:
                break;          
        }
        if(ffflag == 1)
        {
            break;
        }
    }
    if(ffflag == 1)
    {
        printf("第%d用户,退出!\n", *(int *)arg);
        close(*(int *)arg);
    }
}

客户端接口

#include "chat.c"

extern int fflag;                           //跳出登录界面
extern pthread_t tid[2];

void show_welcome()
{
    printf("\n\n\n\n\n\n\n\n");
    printf("\t\t\t\t\t\t\t欢迎来到聊天室!\n");
    printf("\t\t\t\t\t\t     WELCOME TO CHAT ROOM!\n");
    printf("\n\n\n\n");
    printf("\t\t\t\t1.登录帐号\n");
    printf("\n");
    printf("\t\t\t\t2.注册帐号\n");
    printf("\n");
    printf("\t\t\t\t3.忘记密码\n");
    printf("\n");
    printf("\t\t\t\t4.退出\n");
    printf("\n\n\n\n\n\n");
}


/********************************************************用户注册**********************************************/

void show_sign()
{
    printf("\n\n\n\n\n\n\n\n");
    printf("\t\t\t\t请输入帐号:\n");
    printf("\n");
    printf("\t\t\t\t请输入密码:\n");
    printf("\n");
    printf("\t\t\t\t请输入昵称:\n");
    printf("\n");
    printf("\t\t\t\t帅哥输入0,美女输入1:\n");
    printf("\n");
    printf("\t\t\t\t请输入手机号:\n");
    printf("\n\n\n\n\n\n\n");
}


void sign_in(int sockfd)
{
//  system("clear");
    show_sign();
    int ret;

    int userid;
    char userpassword[20];
    char usernickname[20];
    int usersex;
    char usertelephone[20];

    scanf("%d %s %s %d %s", &userid, userpassword, usernickname, &usersex, usertelephone);

    commu userinfor;
    memset(&userinfor, 0, sizeof(userinfor));
    userinfor.idnumber = userid;
    strcpy(userinfor.password, userpassword);
    strcpy(userinfor.nickname, usernickname);
    userinfor.sex = usersex;
    strcpy(userinfor.telephone, usertelephone);
    userinfor.flag = SIGN;

//  printf("%d %s %s %d %s\n", userid, userpassword, usernickname, usersex, usertelephone);
//  printf("flag1:%d\n", userinfor.flag);

    ret = send(sockfd, &userinfor, sizeof(userinfor), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

    memset(&userinfor, 0, sizeof(userinfor));
    ret = recv(sockfd, &userinfor, sizeof(userinfor), 0);
    if(-1 == ret)
    {
        perror("recv");
        exit(1);
    }
//  printf("flag2:%d\n", userinfor.flag);

    if(userinfor.flag == ERROR1)
    {
        printf("注册失败,账户已存在!\n");
    }
    else if(userinfor.flag == RIGHT)
    {
        printf("注册成功!\n");
    }
    return;
}

/************************************************用户登录************************************************/

void show_logo()
{

    printf("\n\n\n\n\n\n\n\n");
    printf("\t\t\t\t请输入帐号:\n");
    printf("\n");   
    printf("\t\t\t\t请输入密码:\n");
    printf("\n\n\n\n\n\n");

}


void logo_in(int sockfd)
{
    int userid, ret;
    char userpassword[20];
//  system("clear");
    show_logo();

    commu userinfor;
    memset(&userinfor, 0, sizeof(userinfor));

    scanf("%d %s", &userinfor.idnumber, userinfor.password);
    userinfor.flag = LOGO;  

    ret = send(sockfd, &userinfor, sizeof(userinfor), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

    memset(&userinfor, 0, sizeof(userinfor));
    ret = recv(sockfd, &userinfor, sizeof(userinfor), 0);
    if(-1 == ret)
    {
        perror("recv");
        exit(1);
    }

    if(userinfor.flag == ERROR1)
    {
        printf("登录失败,该用户未注册!\n");
    }
    else if(userinfor.flag == FAILURE)
    {
        printf("登录失败,该用户已在线!\n");
    }
    else if(userinfor.flag == ERROR2)
    {
        printf("登录失败,帐号密码错误!\n");
    }
    else
    {
        printf("登录成功!\n");
        fflag = 1;
    }

    return;
}

/**************************************************忘记密码*****************************************/

void show_forget()
{
    printf("\n\n\n\n\n\n\n\n");
    printf("\t\t\t\t\t\t\t请输入以下注册时输入的信息\n");
    printf("\n\n\n\n");
    printf("\t\t\t\t请输入帐号:\n");
    printf("\n");
    printf("\t\t\t\t请输入昵称:\n");
    printf("\n");
    printf("\t\t\t\t请输入性别:\n");
    printf("\n");
    printf("\t\t\t\t请输入手机号:\n");
    printf("\n\n\n\n");
    printf("\t\t\t\t请输入您的选择:\n");
    printf("\n\n");
}


void forget_password(int sockfd)
{
    int userid, ret;
    char usernickname[20];
    int usersex;
    char usertelephone[20];
//  system("clear");
    show_forget();
    scanf("%d %s %d %s", &userid, usernickname, &usersex, usertelephone);

    commu userinfor;
    memset(&userinfor, 0, sizeof(userinfor));
    userinfor.idnumber = userid;
    strcpy(userinfor.nickname, usernickname);
    userinfor.sex = usersex;
    strcpy(userinfor.telephone, usertelephone);
    userinfor.flag = FORGET;

    ret = send(sockfd, &userinfor, sizeof(userinfor), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

    memset(&userinfor, 0, sizeof(userinfor));
    ret = recv(sockfd, &userinfor, sizeof(userinfor), 0);
    if(-1 == ret)
    {
        perror("recv");
        exit(1);
    }

    if(userinfor.flag == ERROR1)
    {
        printf("该用户不存在!\n");
    }
    else if(userinfor.flag == FAILURE)
    {
        printf("该用户已在线!\n");
    }
    else if(userinfor.flag == RIGHT)
    {
        printf("帐号密码是:%s\n", userinfor.password);
    }

    return;
}

/*************************************************登录界面退出******************************************/

void client_quit(int sockfd)
{
    commu SendBuf;
    int ret;
    memset(&SendBuf, 0, sizeof(SendBuf));
    SendBuf.flag = QUIT;
    ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

    close(sockfd);
    fflag = 2;
    return;
}

/***************************************************跳转界面******************************************/

void show_in()
{
//  system("clear");
    printf("\n\n\n\n\n\n\n\n");
    printf("\t\t\t\t\t\t\t欢迎进入聊天室!\n");
    printf("\n\n\n\n\n\n\n");
    printf("\t\t\t\t\t\t\t\t\t\t\t正在连接服务器...\n");
    printf("\n\n\n\n\n\n");
}

/***************************************************退出界面****************************************/

void show_quit()
{
    printf("\n\n\n\n\n\n\n\n");
    printf("\t\t\t\t\t正在退出...\n");
//  sleep(2);
//  system(clear");
    printf("\n\n\n\n\n\n\n\n");
    printf("\t\t\t\t\t\t\t再见!\n");
    printf("\n");
    printf("\t\t\t\t\t\t\tGOOD BYE\n");
    printf("\n\n\n\n\n\n\n");
//  system("clear");
    return;
}

/***************************************************主菜单*****************************************/

void show_menu()
{
    printf("\n\n");
    printf("\t\t\t\t\t\t\t\t主菜单\n");
    printf("\n\n\n");
    printf("\t\t\t\t1 . 私聊\n");
    printf("\n");
    printf("\t\t\t\t2 . 群聊\n");
    printf("\n");
    printf("\t\t\t\t3 . 注销\n");
    printf("\n");
    printf("\t\t\t\t4 . 退出\n");
    printf("\n");
    printf("\t\t\t\t5 . 刷新\n");
    printf("\n\n\n");
    printf("\t\t\t\t请输入您的选择:\n");
}

void *client_menu(void *arg)
{
    int jihao = 0;
    char choice[10] = {0};
//  system("clear");

    while(1)
    {
        show_menu();
        printf("\n\n");
        show_people(*(int *)arg);
        scanf("%s", choice);
        switch (atoi(&choice[0]))
        {
            case 1:
                private_chat(arg);
                break;
            case 2:
                group_chat(*(int *)arg);
                break;
            case 3:
                client_back(*(int *)arg);
                jihao = 1;
                break;
            case 4:
                client_cquit(*(int *)arg);
                jihao = 1;
                break;
            default:
                break;
        }
        if(1 == jihao)
        {
            pthread_cancel(tid[1]);
            return;
        }
    }
}

/**********************************************接受消息********************************************/

void *Recv(void *arg)
{
    static cendflag = 0;
    int ret, oldtype;
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);

    commu RecvBuf;
    while(1)
    {
        memset(&RecvBuf, 0, sizeof(RecvBuf));
        ret = recv(*(int *)arg, &RecvBuf, sizeof(RecvBuf), 0);
        if(-1 == ret)
        {
            perror("Recv");
            exit(1);
        }
//      printf("recvbuf:%d\n", RecvBuf.flag);

        if(RecvBuf.flag == FAILURE)
        {
            printf("\n\n");
            printf("发送失败,用户%s不在线!\n", RecvBuf.nickname);
            printf("\n\n");
        }
        else if(RecvBuf.flag == ERROR1)
        {
            printf("\n\n");
            printf("消息发送失败,当前用户只有您一个人在线!\n");
            printf("\n\n");
        }
        else if(RecvBuf.flag == SHOWNUM)
        {
            printf("\n\n");
            printf("当前在线人数:%d\n", RecvBuf.num);
            printf("\n\n");
        }
        else if(RecvBuf.flag == SHOW)
        {
            if(RecvBuf.endflag == 0)
            {
                printf("\t\t%d. %s\n", cendflag + 1, RecvBuf.nickname);
                cendflag++;
            }
            else if(RecvBuf.endflag == 1)
            {
                printf("\t\t%d. %s\n", cendflag + 1, RecvBuf.nickname);
                cendflag = 0;
                printf("\n\n");
            }
        }
        else if(RecvBuf.flag == GCHAT)
        {
            printf("\n\n");
            printf("您有新的群消息:\n");
            printf("\t\t\t\t%s对您说:%s\n", RecvBuf.Fromnickname, RecvBuf.message);
            printf("\n\n");
        }
        else if(RecvBuf.flag == PCHAT)
        {
            printf("\n\n");
            printf("您有新消息:\n");
            printf("\t\t\t\t%s对您说:%s\n", RecvBuf.Fromnickname, RecvBuf.message);
            printf("\n\n");
        }
    }

    return;
}

/***********************************************显示在线人数*****************************************/

void show_people(int sockfd)
{
    int ret, j = 0, i = 0;
    commu SendBuf;
    memset(&SendBuf, 0, sizeof(SendBuf));
    SendBuf.flag = SHOW;
    ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }
    return;
}

/*************************************************私聊*********************************************/

void private_chat(void *arg)
{
    int ret, oldtype;
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);

    while(1)
    {
        printf("\t\t\t\t请输入私聊对象的昵称:\n");
        printf("\n");
        printf("\t\t\t\t请输入私聊内容:\n");

        char cnickname[20] = {0};
        char cmessage[100] = {0};
        scanf("%s %s", cnickname, cmessage);

        commu SendBuf;
        memset(&SendBuf, 0, sizeof(SendBuf));
        strcpy(SendBuf.nickname, cnickname);
        strcpy(SendBuf.message, cmessage);
        SendBuf.flag = PCHAT;

        ret = send(*(int *)arg, &SendBuf, sizeof(SendBuf), 0);
        if(-1 == ret)
        {
            perror("send");
            exit(1);
        }

        if(!strcmp(SendBuf.message, "#end"))
        {
            break;
        }

        return;
    }

    return;
}

/************************************************群聊*********************************************/

void group_chat(int sockfd)
{
    int ret;
    commu SendBuf;

    printf("请输入想要发送的消息:\n");
    scanf("%s", SendBuf.message);
    SendBuf.flag = GCHAT;

    ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }
    return;
}

/****************************************客户端menu回主界面(注销)**********************************/

void client_back(int sockfd)
{
    commu SendBuf;
    int ret;
    memset(&SendBuf, 0, sizeof(SendBuf));
    SendBuf.flag = BACK;
    ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

    return;
}

/**********************************************客户端退出*****************************************/

void client_cquit(int sockfd)
{
    commu SendBuf;
    int ret;
    memset(&SendBuf, 0, sizeof(SendBuf));
    SendBuf.flag = CQUIT;
    ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
    if(-1 == ret)
    {
        perror("send");
        exit(1);
    }

    pthread_cancel(tid[1]);
    client_quit(sockfd);
    fflag = 2;

    return;
}
  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值