C 版本聊天室 C/S架构——服务器程序

/*****************************************************************************
   MARK:客户端命令                       常用表情
    0登录界面                             -HELLO       \( ̄︶ ̄)> 
    1注册                               -LOVE         ( ̄▽ ̄)~*
    2登录                               -BISHI        ( ̄ε  ̄)
    3修改密码                             -HAIXIU       (≧﹏ ≦) 
    4退出程序/退出登录
    5YES                                姓名替换
    6NO                                   /ClientA/HOME
    7聊天界面                             ClientA 大侠,快放小人回家过年
    8私聊
    9群聊
    10查看注册用户
    11查看在线用户
    12踢人
    13禁言
    14查看聊天记录
    19返回登录界面
    20查看帮助

   Send cmd :通信命令     MARK
    1注册用户            1注册
    2登录用户            2登录
    3发送私聊消息      8私聊
    4广播              9群聊
    5询问数据库记录         10查看注册用户
    6询问在线用户      11查看在线用户
    7踢人              12踢人
    8禁言              13禁言
    9下线请求            19返回登录界面




  request result:服务器命令(READ)
    0 服务器断开连接
    11注册成功 10注册失败 
    21登录成功 20登录失败 22强制登录     23vip登录成功  24聊天室已满
    31私聊成功 30私聊失败 32收到私聊     33拒绝发给自己 34找到私聊对象 35禁言无法私聊
    41广播成功            42收到广播                    44找到广播对象 45禁言无法广播
    51数据库记录访问成功 
    61在线记录访问成功      
    71踢人成功 70踢人失败 72收到被踢消息 73拒绝踢自己   74找到被踢的人
    81禁言成功 80禁言失败 82收到禁言消息 83拒绝禁言自己 84找到被禁言的人
    91下线                  92强制下线
    100没有权限
                                                        Mini_chatroom
                                                        copyright by 陈志辉
*****************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sqlite3.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SERV_PORT 9000

#define BUFF_SIZE 1024

int ERROR;
struct user
{
    int socketfd;
    int toSocketfd;
    char name[20];
    char toName[20];
    char msg[100];
    int result;
    int cmd;  
    int nrow;
    int ncolumn;
    char resultp[40][20];   
    char catalogue[20][20];
    int num;
    int vip[20];
    int silence[20];
};

struct userManage
{
    int flag[20];   // 表明哪个空缺 
    int silence[20];
    int vip[20];
    struct user users[20];
};

struct userManage uMge; 

pthread_mutex_t mutex;

void Initsystem()
{
    ERROR = 0;
    int i;
    int fd;

    printf("正在初始化用户管理\n");
    memset(&uMge, 0, sizeof(uMge)); 
    for(i = 0; i<20; i++)
    {
        uMge.flag[i] = 0;
        uMge.silence[i] = 0;
        uMge.vip[i] = 0;
    }

    printf("正在初始化聊天记录\n");
    fd = open("Server_log.txt", O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IXUSR);
    if (-1 == fd)
    {
        perror("open bb.c");
    }
    close(fd);

    printf("正在检查数据库文件\n");
    fd = open("chatroom.db", O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IXUSR);
    if (-1 == fd)
    {
        perror("open bb.c");
    }
    close(fd);

    char buff[200];
    sqlite3 * db = NULL;
    char *errmsg;
    char **resultp = NULL;
    int nrow, ncolumn;
    int ret = sqlite3_open("chatroom.db", &db);
    if (ret != SQLITE_OK)
    {
        printf ("open chatroom.db error!\n");
    }
    ret = sqlite3_exec(db, "create table if not exists student(name TEXT, passward TEXT, vip INTEGER, primary key(name))", NULL, NULL, &errmsg);
    if (ret != SQLITE_OK)
    {
        printf ("create fail:%d(%s)\n", ret ,errmsg);
    }

    printf("初始化vip账户CZH 密码123\n");
    ret = sqlite3_get_table(db, "select name,passward,vip from student where name = 'CZH'", &resultp, &nrow, &ncolumn, &errmsg);                                             
    if (ret != SQLITE_OK)
    {
        printf ("select student table error : %d(%s)!\n", ret, errmsg);
        ERROR = -2;                                             
        printf("ERROR = %d\n", ERROR);
    }
    if(nrow == 0)
    {   
        ret = sqlite3_exec(db, "insert into student values('CZH', '123', 1)", NULL, NULL, &errmsg);
        if (ret != SQLITE_OK)
        {
            printf ("insert student table error : %d(%s)!\n", ret, errmsg);
        }  
        else
        {
            printf("vip账户注册成功\n");      
        }
    } 
    else
    {
        printf("vip账户已存在\n");
    }
    sqlite3_close(db);//关闭数据库   
    printf("服务器初始化完成\n");
}

void Register(int socket_fd, struct user * userInfo)
{
    printf("#1\n");
    sqlite3 * db = NULL;
    char *errmsg;
    char **resultp = NULL;
    int nrow, ncolumn;
    int i; 
    char buff[200];

    int result = sqlite3_open("chatroom.db", &db);//打开数据库文件
    if (result != SQLITE_OK)
    {
        printf ("open chatroom.db error!\n");
        ERROR = -1;
        printf("ERROR = %d\n", ERROR);
    }
    //检测数据库是否有重复用户  

    sprintf (buff, "select name,passward,vip from student where name = '%s'", userInfo->name);
    result = sqlite3_get_table(db, buff, &resultp, &nrow, &ncolumn, &errmsg);                                             
    if (result != SQLITE_OK)
    {
        printf ("select student table error : %d(%s)!\n", result, errmsg);
        ERROR = -2;                                             
        printf("ERROR = %d\n", ERROR);
    }
    if(nrow == 0)//该用户是新用户 result = 11                          //ncolumn多少列    
    {                                                                   //nrow 多少行数据
        printf("添加新用户:%s\n",userInfo->name);//数据库添加新用户      //resultp 数组
        printf("用户密码:%s\n",userInfo->msg);
        sprintf (buff, "insert into student values('%s', '%s', 0)", userInfo->name, userInfo->msg);
        result = sqlite3_exec(db, buff, NULL, NULL, &errmsg);
        if (result != SQLITE_OK)
        {
            printf ("insert student table error : %d(%s)!\n", result, errmsg);
            ERROR = -3;
            printf("ERROR = %d\n", ERROR);
        }      
        for (i = 0; i < 20; i++) //注册完成自动登录
        {
            if (uMge.flag[i] == 1)
            {
                continue;
            }
            uMge.users[i].socketfd = socket_fd;
            strcpy(uMge.users[i].name, userInfo->name);
            userInfo->result = 11;
            uMge.flag[i] = 1;   
            break;
        }        
    }
    else//该用户已存在 result = 10
    {
        printf("用户注册失败\n");
        userInfo->result = 10;//注册失败返回参数
    }
    //################################打印所有用户信息##############################
    result = sqlite3_get_table(db, "select * from student", &resultp, &nrow, &ncolumn, &errmsg);  //打印所有用户信息                                           
    if (result != SQLITE_OK)
    {
        printf ("select student table error : %d(%s)!\n", result, errmsg);
        ERROR = -4;
        printf("ERROR = %d\n", ERROR);
    }   
    int count = 0;
    for (i = 0; i < (nrow+1)*ncolumn; i++)  //ncolumn多少列                                         
    {                                       //nrow 多少行数据
        count++;                            //resultp 数组
        printf ("%8s ", resultp[i]);
        if (count % ncolumn == 0)
        {
            printf ("\n");
        }
    }
    printf ("\n");  
    //###################################################################################
    sqlite3_close(db);//关闭数据库   
}
void Load(int socket_fd, struct user * userInfo)
{
    printf ("#2\n");
    sqlite3 * db = NULL;
    char *errmsg;
    char **resultp = NULL;
    int nrow, ncolumn;
    char buff[200]; 
    int i;
    int vip = 0;

    int result = sqlite3_open("chatroom.db", &db);//打开数据库文件
    if (result != SQLITE_OK)
    {
        printf ("1open chatroom.db error!\n");
        ERROR = -5;
        printf("ERROR = %d\n", ERROR);
    }       
    //验证用户账号密码
    sprintf (buff, "select passward from student where name='%s'", userInfo->name);
    result = sqlite3_get_table(db, buff, &resultp, &nrow, &ncolumn, &errmsg);                                             
    if (result != SQLITE_OK)
    {
        printf ("select student table error : %d(%s)!\n", result, errmsg);  
        ERROR = -7;
        printf("ERROR = %d\n", ERROR);
    }
    if(nrow == 0)//账户不存在 result = 20 
    {
        //printf("%d %d\n",ncolumn,nrow);
        printf("该用户不存在\n");
        printf ("%s\n", userInfo->name);
        userInfo->result = 20;//登录失败返回参数
    }
    else
    {
        printf("验证用户密码\n");
        if(!strcmp(userInfo->msg, resultp[ncolumn]))
        {
            printf("密码正确\n");       
            //检查重复登录
            for (i = 0; i < 20; i++)
            {
                if(uMge.flag[i] == 1)
                {
                    if(strcmp(uMge.users[i].name, userInfo->name) == 0 && uMge.users[i].socketfd !=userInfo->socketfd)//账户相同 密码正确
                    {
                        printf("检测到用户:%s重复登录\n默认强制登录\n");
                        userInfo->toSocketfd = uMge.users[i].socketfd;//记录socket
                        uMge.users[i].socketfd = userInfo->socketfd;    //替换socket                  
                        userInfo->result = 22; //强制登录
                        break;
                    }       
                }                   
            }   
            if(userInfo->result != 22)
            {
                //验证vip 
                sprintf (buff, "select vip from student where name='%s'", userInfo->name);  
                result = sqlite3_get_table(db, buff, &resultp, &nrow, &ncolumn, &errmsg);                                             
                if (result != SQLITE_OK)
                {
                    printf ("select vip student table error : %d(%s)!\n", result, errmsg);  
                }
                if(resultp[ncolumn][0] == '1')
                {
                    printf("检测到vip账户登录\n");
                    vip = 1;
                }
                for (i = 0; i < 20; i++)//服务器列表添加用户名    
                {
                    if (uMge.flag[i] == 1)
                    {
                        continue;
                    }
                    uMge.users[i].socketfd = socket_fd;
                    strcpy(uMge.users[i].name, userInfo->name);
                    uMge.flag[i] = 1;
                    if(vip)
                    {
                        userInfo->result = 23;
                        printf ("vip账户%s 登录成功", uMge.users[i].name);
                        uMge.vip[i] = 1;
                        break;
                    }
                    else
                    {
                        userInfo->result = 21;//登录成功返回参数                    
                        printf ("账户%s 登录成功\n", uMge.users[i].name);     
                        break;
                    }
                }                       
                printf ("%s 上线了!\n", uMge.users[i].name);   
            }
        }
        else
        {
            printf("密码错误\n");
            userInfo->result = 20;//登录失败返回参数 
        }
    }   
    sqlite3_close(db);//关闭数据库   
}
void Send_alone(int socket_fd, struct user * userInfo)
{
    printf ("#3\n");
    int i;
    int silence;
    //################################打印在线用户信息##############################
    for(i = 0; i < 20; i++)//打印所有用户信息
    {
        if (uMge.flag[i] == 1)
        {
            printf("%d %s \n",uMge.users[i].socketfd,uMge.users[i].name);
        }
    }
    //##############################################################################
    for(i = 0; i < 20; i++)
    {
        if( uMge.flag[i]== 0)
        {
            continue;
        }
        if(strcmp(uMge.users[i].name, userInfo->name) == 0)
        {
            if(uMge.silence[i] == 1)
            {
                silence = 1;
            }
            else
            {
                silence = 0;
            }
        }
    }
    if(silence)
    {
        userInfo->result = 35;
    }
    else
    {
        for (i = 0; i < 20; i++)// 寻找要发送的用户
        {
            if (uMge.flag[i] == 1)
            {   

                if(strcmp(uMge.users[i].name, userInfo->toName) == 0)// 找到了要发送的用户
                {
                    if(strcmp(uMge.users[i].name, userInfo->name) == 0)//拒绝恶作剧(发给自己)
                    {
                        userInfo->result = 33;
                        break;
                    }
                    else
                    {
                        userInfo->toSocketfd = uMge.users[i].socketfd;
                        userInfo->result = 34;
                        break;
                    }
                }
            }
        }
        if(userInfo->result != 34 && userInfo->result != 33)
        {   
            userInfo->result = 30;      
        }
    }
}

void Broadcast(int socket_fd, struct user * userInfo)
{
    printf ("#4\n");
    int i;
    int silence;
    for(i = 0; i < 20; i++)
    {
        if( uMge.flag[i]== 0)
        {
            continue;
        }
        if(strcmp(uMge.users[i].name, userInfo->name) == 0)
        {
            if(uMge.silence[i] == 1)
            {
                silence = 1;
            }
            else
            {
                silence = 0;
            }
            break;
        }
    }
    if(silence)
    {
        userInfo->result = 45;
    }
    else
    {
        userInfo->result = 44;
    }
}
void Check_sqlite(int socket_fd, struct user * userInfo)
{
    printf ("#5\n");
    sqlite3 * db = NULL;
    char *errmsg;
    char **resultp = NULL;
    int nrow, ncolumn;
    int i; 
    char buff[200];
    int result = sqlite3_open("chatroom.db", &db);//打开数据库文件
    if (result != SQLITE_OK)
    {
        printf ("open chatroom.db error!\n");
        ERROR = -1;
        printf("ERROR = %d\n", ERROR);
    }
    result = sqlite3_get_table(db, "select name,vip from student", &resultp, &nrow, &ncolumn, &errmsg); 
    if (result != SQLITE_OK)
    {
        printf ("select student table error : %d(%s)!\n", result, errmsg);                                              
        printf("ERROR = %d\n", ERROR);      
    }
    for (i = ncolumn; i < (nrow+1)*ncolumn; i++)    //ncolumn多少列
    {                                               //nrow 多少行数据                                                    
        //printf ("%8s ", resultp[i]);              //resultp 数组
        strcpy(userInfo->resultp[i - ncolumn],resultp[i]);
        printf ("%8s \n", userInfo->resultp[i - ncolumn]);  
    }
    //printf ("%d  %d\n",nrow,ncolumn);
    userInfo->nrow = nrow;
    userInfo->ncolumn = ncolumn;
    userInfo->result = 51;
}
void Check_uMge(int socket_fd, struct user * userInfo)
{
    printf ("#6\n");
    int i;
    int j;
    j = 0;
    /* printf("####1");
    for(i = 0; i < 20; i++)
    {
        printf("%d",uMge.flag[i] );
    } */
    printf("\n");
    for(i = 0; i < 20; i++)
    {
        if (uMge.flag[i] == 1)
        {
            strcpy(userInfo->catalogue[j],uMge.users[i].name);
            userInfo->vip[j] = uMge.vip[i];
            userInfo->silence[j] = uMge.silence[i];
            j++;
        }
    }
    userInfo->result = 61;
    userInfo->num = j;
}
void Kick(int socket_fd, struct user * userInfo)
{
    printf ("#7\n");    
    int i;
    int vip;
    for(i = 0; i < 20; i++)
    {

        if( uMge.flag[i]== 0)
        {
            continue;
        }
        if(strcmp(uMge.users[i].name, userInfo->name) == 0)
        {
            if(uMge.vip[i] == 1)
            {
                vip = 1;
            }
            else
            {
                vip = 0;
            }
        }
    }
    if(vip)
    {
        for(i = 0; i < 20; i++)// 寻找要踢的用户
        {
            if (uMge.flag[i] == 1)
            {
                if(strcmp(uMge.users[i].name, userInfo->toName) == 0)// 找到了要踢的用户
                {
                    if(strcmp(uMge.users[i].name, userInfo->name) == 0)//拒绝恶作剧(发给自己)
                    {
                        userInfo->result = 73;
                        break;
                    }
                    else
                    {
                        userInfo->toSocketfd = uMge.users[i].socketfd;
                        uMge.flag[i] = 0;
                        userInfo->result = 74;
                        break;
                    }
                }
            }
        }
        if(userInfo->result != 74 && userInfo->result != 73)
        {   
            userInfo->result = 70;      
        }
    }
    else
    {
        userInfo->result = 100;
    }
}
void Silence(int socket_fd, struct user * userInfo)
{
    printf ("#8\n");
    int i;  
    int vip;
    for(i = 0; i < 20; i++)
    {
        if( uMge.flag[i]== 0)
        {
            continue;
        }
        if(strcmp(uMge.users[i].name, userInfo->name) == 0)
        {
            if(uMge.vip[i] == 1)
            {
                vip = 1;
            }
            else
            {
                vip = 0;
            }
        }
    }
    if(vip)
    {
        for(i = 0; i < 20; i++)// 寻找要禁言的用户
        {
            if (uMge.flag[i] == 1)
            {
                if(strcmp(uMge.users[i].name, userInfo->toName) == 0)// 找到了要踢的用户
                {
                    if(strcmp(uMge.users[i].name, userInfo->name) == 0)//拒绝恶作剧(发给自己)
                    {
                        userInfo->result = 83;
                        break;
                    }
                    else
                    {
                        uMge.silence[i] = 1;
                        userInfo->toSocketfd = uMge.users[i].socketfd;
                        userInfo->result = 84;
                        break;
                    }
                }
            }
        }
        if(userInfo->result != 84 && userInfo->result != 83)
        {   
            userInfo->result = 80;      
        }
    }
    else
    {
        userInfo->result = 100;     
    }
}
void Offline(int socket_fd, struct user * userInfo)
{
    printf ("#9\n");
    int i;
    for (i = 0; i < 20; i++)
    {
        if (uMge.flag[i] == 0)
        {
            continue;
        }
        if(strcmp(uMge.users[i].name, userInfo->name) == 0)
        {
            printf("用户%s下线\n");
            uMge.flag[i] = 0;
            uMge.silence[i] = 0;
            uMge.vip[i] = 0;
            userInfo->result = 91;
            break;
        }           
    }   
}
/* Send cmd
    1注册用户
    2登录用户
    3发送私聊消息
    9下线请求
*/
void *server_request(int cfd)
{
    int readSize, writeSize;
    struct user userInfo;
    int i;
    int fd;
    int ret;
    char buf[201] = {0};
    while (readSize = read(cfd, &userInfo, sizeof(userInfo)))//阻塞等待数据
    {
        if (readSize == -1)
        {
            perror("read");
            return ;
        }   
        printf("收到用户%s的cmd:%d\n",userInfo.name,userInfo.cmd);
        switch(userInfo.cmd)//处理客户端数据
        {
            case 1://注册
            {
                Register(cfd, &userInfo);
                break;
            }
            case 2://登录
            {
                Load(cfd, &userInfo);
                break;
            }
            case 3://私聊
            {
                Send_alone(cfd, &userInfo);
                break;
            }
            case 4://广播
            {
                Broadcast(cfd, &userInfo);
                break;
            }
            case 5://询问数据库记录
            {
                Check_sqlite(cfd, &userInfo);
                break;
            }
            case 6://询问在线用户
            {
                Check_uMge(cfd, &userInfo);
                break;
            }
            case 7://踢人
            {
                Kick(cfd, &userInfo);
                break;
            }
            case 8://禁言
            {
                Silence(cfd, &userInfo);
                break;
            }
            case 9://下线请求
            {
                Offline(cfd, &userInfo);
                break;
            }
            default :
            {
                printf("错误 收到客户端cmd:%d", userInfo.cmd);
                break;
            }
        }
        printf("result:%d\n",userInfo.result);
        switch(userInfo.result)//向客户端发送数据
        {
            case 10://注册失败
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 11://注册成功
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 20://登录失败
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 21://登录成功
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 22://强制登录
            {
                userInfo.result = 21;
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                userInfo.result = 92;
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(userInfo.toSocketfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 23://vip登录
            {
                printf("向vip用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 30://私聊失败
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 33://拒绝恶作剧发给自己
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 34://找到私聊对象
            {
                userInfo.result = 32;
                printf("向用户%s发送result:%d\n",userInfo.toName,userInfo.result);
                printf("用户%s向用户%s发送一条信息:%s\n", userInfo.name, userInfo.toName, userInfo.msg);
                fd = open("Server_log.txt", O_RDWR | O_APPEND , S_IWUSR | S_IRUSR | S_IXUSR);
                if (-1 == fd)
                {
                    perror("Server_log.txt");
                }
                sprintf(buf, "%s(私聊) send to %s: %s",userInfo.name,userInfo.toName,userInfo.msg);
                ret = write(fd, buf, 200);
                if (-1 == ret)
                {
                    perror("write");
                }
                close(fd);
                writeSize = write(userInfo.toSocketfd, &userInfo, sizeof(userInfo));

                userInfo.result = 31;
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 35:
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                printf("用户%s被禁言 发送消息失败\n", userInfo.name);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 44://找到广播对象
            {
                printf("用户%s发送一条群消息:%s\n", userInfo.name, userInfo.msg);
                fd = open("Server_log.txt", O_RDWR | O_APPEND , S_IWUSR | S_IRUSR | S_IXUSR);
                if (-1 == fd)
                {
                    perror("Server_log.txt");
                }
                sprintf(buf, "%s(群消息): %s",userInfo.name,userInfo.msg);
                ret = write(fd, buf, 200);
                if (-1 == ret)
                {
                    perror("write");
                }
                close(fd);          
                userInfo.result = 42;
                for(i = 0; i < 20; i++)
                {
                    if (uMge.flag[i] == 1)
                    {
                        if(strcmp(uMge.users[i].name,userInfo.name) != 0)
                        {
                            strcpy(userInfo.toName,uMge.users[i].name);
                            writeSize = write(uMge.users[i].socketfd, &userInfo, sizeof(userInfo));
                        }
                    }
                } 
                userInfo.result = 41;
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 45:
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                printf("用户%s被禁言 发送群消息失败\n", userInfo.name);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 51://数据库记录访问成功         
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 61://在线记录访问成功          
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 70://踢人失败          
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 73://拒绝踢自己         
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 74://找到被踢的人        
            {
                userInfo.result = 72;
                printf("向用户%s发送result:%d\n",userInfo.toName,userInfo.result);
                printf("用户%s向用户%s发送踢人指令\n", userInfo.name, userInfo.toName);
                writeSize = write(userInfo.toSocketfd, &userInfo, sizeof(userInfo));

                userInfo.result = 71;
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 80://禁言失败          
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 83://拒绝禁言自己            
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 84://找到被禁言的人       
            {
                userInfo.result = 82;

                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                printf("用户%s向用户%s发送禁言指令\n", userInfo.name, userInfo.toName);
                writeSize = write(userInfo.toSocketfd, &userInfo, sizeof(userInfo));

                userInfo.result = 81;
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 91://下线请求允许            
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            case 100://没有权限         
            {
                printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
                writeSize = write(cfd, &userInfo, sizeof(userInfo));
                break;
            }
            default:
            {
                printf("错误 收到result:%d", userInfo.result);
                break;
            }
        }
        memset(&userInfo, 0, sizeof(userInfo)); 
    }
    int temp;
    temp = 0;
    for (i = 0; i < 20; i++)
    {
        if(uMge.flag[i] == 1)
        {
            if(uMge.users[i].socketfd == cfd)
            {
                printf("检测到用户%s掉线了\n",uMge.users[i].name);
                uMge.flag[i] = 0;
                temp = 1;
                break;
            }   
        }
    }       
    if(!temp)
    {
        printf("检测到用户退出客户端\n");
    } 
} 
/*request result
    11注册成功  10注册失败
    21登录成功  20登录失败  22
    31私聊成功  30私聊失败  32收到私聊 33拒绝恶作剧发给自己

    91下线
*/

int main()
{

    Initsystem();
    int listen_sockfd;
    int ret;
    struct sockaddr_in server_addr;  // 服务器地址结构
    struct sockaddr_in client_addr;  // 客户端的地址

    pthread_mutex_init(&mutex, NULL);

    // 创建监听套接字
    listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_sockfd == -1)
    {
        perror("create socket error");
        return -1;
    }

    // 初始化服务器地址结构
    bzero(&server_addr, sizeof(server_addr));          // 将地址结构变量清零
    server_addr.sin_family = AF_INET;                  // 选择IPV4地址
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);   // 监听本地任意IP地址
    server_addr.sin_port = htons(SERV_PORT);           // 将本地端口号转化为网络端口号

    // 绑定本地地址和端口号
    ret = bind(listen_sockfd, (struct sockaddr *)&server_addr, sizeof (server_addr));
    if (ret == -1)
    {
        perror ("bind error");
        return -1;
    }

    // 监听套接字
    ret = listen(listen_sockfd, 20);
    if (ret == -1)
    {
        perror("listen error");
        return -1;
    }

    while(1)
    {
        int clientfd;
        socklen_t client_len = sizeof(client_addr);

        clientfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &client_len);
        if (clientfd == -1)
        {
            perror("accept error");
            return -1;
        }           

        pthread_t tid;
        // 创建线程处理客户端请求
        int ret = pthread_create(&tid, NULL, (void *)server_request, (void *)clientfd);
        if (ret != 0)
        {
            printf ("create pthread error!\n");
            return -1;
        }
        printf("检测到用户打开客户端\n");
        pthread_detach(tid); // 线程分离
    }

    pthread_mutex_destroy(&mutex);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值