美文网首页
“掌中”通讯

“掌中”通讯

作者: 坏z孩子 | 来源:发表于2017-03-07 14:26 被阅读0次

    1.client

    #include <stdio.h>
    #include <string.h>
    /*socket() connect()  recv()*/
    #include <sys/types.h> 
    #include <sys/socket.h>
    #include <netinet/in.h>  //struct sockaddr_in
    #include <pthread.h>  //thread
    #include "../protocol/protocol.h"
    #include "../link/node.h"
    #include "../fileLink/fileNode.h"
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <arpa/inet.h>
    #include <signal.h>
    
    //#define SERVER 0;
    
    int g_iId=0;
    int g_ifOnline=2;
    int g_iFlag=0;
    int g_iPass=0;
    int g_iSockfd=0;
    Head *g_pHead=NULL;
    //fileHead
    #define MAXLEN 1024
    
    void sendDataToServer(int sockfd,ChatPDU *pChatPDU)
    {
        if(pChatPDU==NULL)
        {
            return ;
        }
        int iLen=pChatPDU->iChatPDULen;
        int iLeft=iLen;
        int iSend=0;
        int ret=0;
    
        ret=send(sockfd,pChatPDU,iLen,0);
        iLeft-=ret;
        iSend+=ret;
        while(ret>0&&iLen)
        {
            ret=send(sockfd,(char *)pChatPDU+iSend,iLeft,0);
            iLeft-=ret;
            iSend+=ret;
    
        }
    }
    
    
    //获取信息
    ChatPDU * readDataFromServer(int sockfd)
    {
        int ret=0;
        unsigned int iPDULen=0;
        ret=recv(sockfd,&iPDULen,sizeof(int),0);
        if(ret==-1)
        {
            perror("recv");
            return NULL;
        }
        ChatPDU *pChatPDU=(ChatPDU *)malloc(iPDULen);
        memset(pChatPDU,0,iPDULen);
        pChatPDU->iChatPDULen=iPDULen;
        int iLeft=iPDULen-ret;
        int iRecv=ret;
        while(ret>0&&iLeft)//不能保证一次性收完,循环接收
        {
            ret=recv(sockfd,(char *)pChatPDU+iRecv,iLeft,0);
            iRecv+=ret;
            iLeft-=ret;
        }
        return pChatPDU;
    }
    
    //私聊
    void chatPrivate(int sockfd)
    {
        printf("请输入你想聊天的对象id:");
        int iId=0;
        char caBuf[MAXLEN]={'\0'};
        int iLen=0;
        scanf("%d",&iId);
        ChatPDU *pChatPDU=NULL;
        while(1)
        {
            scanf("%s",caBuf);
            if(strcmp(caBuf,"quit")==0)
            {
                return ;
            }
            iLen=sizeof(ChatPDU)-sizeof(int)+strlen(caBuf)+1;
            pChatPDU=makeChatPDU(iLen);
            pChatPDU->iChatPDULen=iLen;
            pChatPDU->iChatDataLen=strlen(caBuf)+1;
            pChatPDU->iFROM=g_iId;
            pChatPDU->iTO=iId;
            strcpy(pChatPDU->chatData,caBuf);
            pChatPDU->iTYPE=ENUM_TYPE_CHAT_PRICATE_GO;
            sendDataToServer(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
        }
    
        
    }
    //收获私聊信息
    void getChatPrivateData(ChatPDU *pChatPDU)
    {
        printf("                                 %s:%s\n",pChatPDU->data.caName,pChatPDU->chatData);
        free(pChatPDU);
        pChatPDU=NULL;
        
    }
    
    //收获私聊通知
    void chatPrivateSend(ChatPDU *pChatPDU)
    {
        printf("你的好友不在线\n");
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //查看所有用户
    void sendToAskAllUsr(int sockfd)
    {
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iTYPE=ENUM_TYPE_ASK_ALL_ID_GO;
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        sendDataToServer(sockfd,pChatPDU);
        printf("所有人员:\n");
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
        
    }
    //收获查看所有用户返回
    void getAskAllUsrBack(ChatPDU *pChatPDU)
    {
        
        printf("id=%d,name=%s\n",pChatPDU->data.iId,pChatPDU->data.caName);
        if(pChatPDU->data.ifOnline==0)
        {
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //查看在线用户
    void sendToAskOnlineUsr(int sockfd)
    {
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iTYPE=ENUM_TYPE_ASK_ID_GO;
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        sendDataToServer(sockfd,pChatPDU);
        printf("在线人员:\n");
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    
    }
    //收获查看在线用户返回
    void getAskOnlineUsrBack(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==0)
        {
            printf("id=%d,name=%s\n",pChatPDU->data.iId,pChatPDU->data.caName);
        }
        else if(pChatPDU->data.ifLogin==1)
        {
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //发送修改密码
    void sendChangePasswordPlease(int sockfd)
    {
        int iPass1=0,iPass2=0;
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iTYPE=ENUM_TYPE_CHANGE_PASSWORD_GO;
        pChatPDU->iFROM=g_iId;
        while(1)
        {
            printf("请输入你的旧密码:");
            system("stty -echo");
            scanf("%d",&iPass1);
            system("stty echo");
            printf("\n");
            if(iPass1==g_iPass)
            {
                while(1)
                {
                    printf("请输入你的新密码:");
                    system("stty -echo");
                    scanf("%d",&iPass1);
                    system("stty echo");
                    printf("\n");
                    printf("请再次输入你的新密码:");
                    system("stty -echo");
                    scanf("%d",&iPass2);
                    system("stty echo");
                    printf("\n");
                    if(iPass1==iPass2)
                    {
                        pChatPDU->data.iPassword=iPass1;
                        sendDataToServer(sockfd,pChatPDU);
                        free(pChatPDU);
                        pChatPDU=NULL;
                        sleep(1);
                        return ;
                    }
                    else
                    {
                        printf("两次密码输入不一致\n");
                    }
                
                }
            }
            else
            {
                printf("旧密码错误,请重新输入\n");
            }
        }
    }
    
    #if 1
    //写日志
    void sendWriteDailyData(int sockfd)
    {
        char caBuf[64]={'\0'};
        scanf("%s",caBuf);
        int iLen=sizeof(ChatPDU)-sizeof(int)+strlen(caBuf)+1;
        ChatPDU *pChatPDU=makeChatPDU(iLen);
        pChatPDU->iFROM=g_iId;
        pChatPDU->iTYPE=ENUM_TYPE_WRITE_DAILY_GO;
        strcpy(pChatPDU->chatData,caBuf);
        pChatPDU->iChatPDULen=iLen;
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
    
    }
    //查看某人日志
    void sendReadDailyData(int sockfd)
    {
    
        int iId;
        printf("请输入你要查看的对象id:");
        scanf("%d",&iId);
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iTYPE=ENUM_TYPE_READ_DAILY_GO;
        pChatPDU->iFROM=g_iId;
        pChatPDU->iTO=iId;
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    }
    
    //收取查看某人日志返回
    void getReadDaileData(ChatPDU *pChatPDU)
    {
        if(strcmp(pChatPDU->chatData,"\0")==0)
        {
            printf("%s没有写日志\n",pChatPDU->data.caName);
            g_iFlag=1;
        }
        else
        {
            printf("%s:%s\n",pChatPDU->data.caName,pChatPDU->chatData);
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    #endif
    
    //创建群组
    void sendSetGroup(int sockfd)
    {
        printf("请输入你的群组名:");
        char caBuf[32]={'\0'};
        scanf("%s",caBuf);
        int iLen=sizeof(ChatPDU)-sizeof(int)+strlen(caBuf)+1;
        ChatPDU *pChatPDU=makeChatPDU(iLen);
        pChatPDU->iChatPDULen=iLen;
        pChatPDU->iTYPE=ENUM_TYPE_SET_GROUP_GO;
        pChatPDU->iFROM=g_iId;
        strcpy(pChatPDU->chatData,caBuf);
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    
    
    }
    
    //收获创建群组返回
    void getSetGroupBack(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==0)
        {
            printf("群组名已存在,请重新创建\n");
            g_iFlag=1;
        }
        else
        {
            printf("群组创建成功\n");
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    #if 1
    //拉人
    void pullPeopleInGroup(int sockfd)
    {
        printf("请输入你要邀请对象的id:");
        int iId;
        scanf("%d",&iId);
        int iLen=sizeof(ChatPDU);
        ChatPDU *pChatPDU=makeChatPDU(iLen);
        pChatPDU->iChatPDULen=iLen;
        pChatPDU->iTYPE=ENUM_TYPE_IN_GROUP_GO;
        pChatPDU->iFROM=g_iId;
        pChatPDU->iTO=iId;
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    }
    //收获拉人返回
    void getPullPeopleInGroupBack(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==0)
        {
            printf("邀请失败:该用户不存在\n");
            g_iFlag=1;
        }
        else if(pChatPDU->data.ifLogin==1)
        {
            printf("邀请失败:该用户已经是群成员了\n");
            g_iFlag=1;
        }
        else 
        {
            printf("邀请成功\n");
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //邀请通知
    void getPullPeopleInGroupSend(ChatPDU *pChatPDU)
    {
        printf("你已被邀请入群---%s\n",pChatPDU->caFileName);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    #endif
    
    
    //群聊
    void chatGroup(int sockfd)
    {
        char caBuf[MAXLEN]={'\0'};
        int iLen=0;
        ChatPDU *pChatPDU=NULL;
        while(1)
        {
            scanf("%s",caBuf);
            if(strcmp(caBuf,"quit")==0)
            {
                return ;
            }
            iLen=sizeof(ChatPDU)-sizeof(int)+strlen(caBuf)+1;
            pChatPDU=makeChatPDU(iLen);
            pChatPDU->iChatPDULen=iLen;
            pChatPDU->iChatDataLen=strlen(caBuf)+1;
            pChatPDU->iFROM=g_iId;
            pChatPDU->iTO=SERVER;
            strcpy(pChatPDU->chatData,caBuf);
            pChatPDU->iTYPE=ENUM_TYPE_CHAT_GROUP_GO;
            sendDataToServer(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
        }
    
        
    }
    //收获群聊信息
    void getChatGroupData(ChatPDU *pChatPDU)
    {
        printf("                                 %s:%s\n",pChatPDU->data.caName,pChatPDU->chatData);
        free(pChatPDU);
        pChatPDU=NULL;
        
    }
    
    
    //查看群成员
    void sendToAskGroupUsr(int sockfd)
    {
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iTYPE=ENUM_TYPE_ASK_GROUP_ID_GO;
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iFROM=g_iId;
        sendDataToServer(sockfd,pChatPDU);
        printf("群成员:\n");
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
        
    }
    //收获查看群成员返回
    void getAskGroupUsrBack(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==0)
        {
            printf("id=%d,name=%s\n",pChatPDU->data.iId,pChatPDU->data.caName);
        }
        else if(pChatPDU->data.ifLogin==1)
        {
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //设置管理员
    void setAdministrator(int sockfd)
    {
        printf("请输入你要设置对象的id:");
        int iId;
        scanf("%d",&iId);
        int iLen=sizeof(ChatPDU);
        ChatPDU *pChatPDU=makeChatPDU(iLen);
        pChatPDU->iChatPDULen=iLen;
        pChatPDU->iTYPE=ENUM_TYPE_SET_ADMINISTRATOR_GO;
        pChatPDU->iFROM=g_iId;
        pChatPDU->iTO=iId;
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    }
    //收获设置管理员返回
    void getSetAdministratorBack(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==0)
        {
            printf("设置失败,该用户不存在或非群成员\n");
            g_iFlag=1;
        }
        else if(pChatPDU->data.ifLogin==1)
        {
            printf("设置失败,该用户已经是群主或管理员了\n");
            g_iFlag=1;
        }
        else if(pChatPDU->data.ifLogin==3)
        {
            printf("设置失败,权限不足\n");
            g_iFlag=1;
        }
        else 
        {
            printf("设置成功\n");
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    ///////上传文件//////
    void sendDataToServerFromFile(int sockfd)
    {
        printf("请输入你要上传的文件名:");
        char caFileName[64]={'\0'};
        scanf("%s",caFileName);
        int fd=open(caFileName,O_RDONLY);
        if(fd==-1)
        {
            perror("open");
            return ;
        }
        int iLen=lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);
        int iLeft=iLen;
        char caBuf[MAXLEN]={'\0'};
        int ret=read(fd,caBuf,iLeft);
        int iRead=ret;
        while(ret>0 && iLeft)
        {
            ret=read(fd,caBuf,iLeft);
            iLeft-=ret;
            iRead+=ret;     
        }
        int iLenAll=sizeof(ChatPDU)-sizeof(int)+iLen;
        ChatPDU *pChatPDU=makeChatPDU(iLenAll);
        pChatPDU->iTYPE=ENUM_TYPE_UP_FILE;
        pChatPDU->iFROM=g_iId;
        pChatPDU->iTO=SERVER;
        strcpy(pChatPDU->caFileName,caFileName);
        pChatPDU->iChatDataLen=iLen;
        pChatPDU->iChatPDULen=sizeof(ChatPDU)-sizeof(int)+iLen;
        strcpy(pChatPDU->chatData,caBuf);
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        printf("上传成功\n");
        
    }
    
    
    //请求查看服务器文件链表
    void sendAskFileNameFromServer(int sockfd)
    {
        
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iTYPE=ENUM_TYPE_ASK_FILE_GO;
        pChatPDU->iTO=SERVER;
        pChatPDU->iFROM=g_iId;
        sendDataToServer(sockfd,pChatPDU);
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    }
    
    //收获查看文件链表返回
    void getAskFileName(ChatPDU *pChatPDU)
    {
        if(strcmp(pChatPDU->data.caName,"\0")==0)
        {
            printf("暂无文件\n");
            g_iFlag=1;
        }
        else
        {
            printf("%s\n",pChatPDU->data.caName);
            if(pChatPDU->data.ifLogin==1)
            {
                g_iFlag=1;
            }
        }
    
    }
    
    
    //从服务器读取文件
    void readFileFromServer(ChatPDU *pChatPDU)
    {
        char caFileName[128]="./test/";
        strcat(caFileName,pChatPDU->caFileName);
        FILE *fd=fopen(caFileName,"w");
        if(fd==NULL)
        {
            perror("fopen");
            return ;
        }
        fprintf(fd,"%s",pChatPDU->chatData);
        fclose(fd);
        printf("下载成功\n");
        g_iFlag=1;
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //发送下载请求
    void sendPleaseToDownFileFromServer(int sockfd)
    {
        printf("请输入要下载的文件名:");
        char caBuf[64]={'\0'};
        scanf("%s",caBuf);
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iTYPE=ENUM_TYPE_DOWN_FILE_GO;
        pChatPDU->iTO=SERVER;
        pChatPDU->iFROM=g_iId;
        strcpy(pChatPDU->caFileName,caBuf);
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    
    
    }
    
    
    //禁言
    void sendBannedToPost(int sockfd)
    {
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iTYPE=ENUM_TYPE_BANNED_TO_POST_GO;
        pChatPDU->iFROM=g_iId;
        printf("1.全禁言  2.禁言个人\n");
        int select;
        scanf("%d",&select);
        if(select==1)
        {
            sendDataToServer(sockfd,pChatPDU);      
        }
        else
        {
            printf("请选择禁言对象的id:");
            int iId;
            scanf("%d",&iId);
            pChatPDU->iTO=iId;
            sendDataToServer(sockfd,pChatPDU);      
        }
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    }
    
    //禁言返回
    void getBannedToPostBack(ChatPDU *pChatPDU)
    {
        switch(pChatPDU->data.ifLogin)
        {
            case 0:
                printf("禁言失败:你未加入群组\n");
                break;
            case 1:
                printf("禁言失败:权限不足\n");
                break;
            case 2:
                printf("禁言成功\n");
                break;
            case 3:
                printf("禁言失败:该用户不存在\n");
                break;
            case 4:
                printf("禁言失败:该用户已经被禁言\n");
                break;
            case 5:
                printf("禁言成功\n");
                break;
        }
        g_iFlag=1;
        free(pChatPDU);
        pChatPDU=NULL;
    }
    //被禁言提醒
    void getBannedToPostSend(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==2)
        {
            printf("管理员已设置全员禁言\n");
        }
        else if(pChatPDU->data.ifLogin==5)
        {
            printf("你已被管理员禁言\n");
        }
        else if(pChatPDU->data.ifLogin==3)
        {
            printf("禁言中。。。\n");
        }
        else if(pChatPDU->data.ifLogin==4)
        {
            printf("未加入群组\n");
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //解禁言
    void sendLiftBanned(int sockfd)
    {
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iTYPE=ENUM_TYPE_LIFT_BAN_GO;
        pChatPDU->iFROM=g_iId;
        printf("1.全解禁言  2.解禁个人\n");
        int select;
        scanf("%d",&select);
        if(select==1)
        {
            sendDataToServer(sockfd,pChatPDU);      
        }
        else
        {
            printf("请选择解禁言对象的id:");
            int iId;
            scanf("%d",&iId);
            pChatPDU->iTO=iId;
            sendDataToServer(sockfd,pChatPDU);      
        }
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    }
    
    
    //解禁言返回
    void getLiftBannedBack(ChatPDU *pChatPDU)
    {
        switch(pChatPDU->data.ifLogin)
        {
            case 0:
                printf("解禁言失败:你未加入群组\n");
                break;
            case 1:
                printf("解禁言失败:权限不足\n");
                break;
            case 2:
                printf("解禁言成功\n");
                break;
            case 3:
                printf("解禁言失败:该用户不存在\n");
                break;
            case 4:
                printf("解禁言失败:该用户未被禁言\n");
                break;
            case 5:
                printf("解禁言成功\n");
                break;
        }
        g_iFlag=1;
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //被禁言提醒
    void getLiftBannedSend(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==2)
        {
            printf("管理员已设置全员解禁言\n");
        }
        else if(pChatPDU->data.ifLogin==5)
        {
            printf("你已被管理员解禁言\n");
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //踢人
    void pullPeopleOutGroup(int sockfd)
    {
        printf("请输入你要踢出对象的id:");
        int iId;
        scanf("%d",&iId);
        int iLen=sizeof(ChatPDU);
        ChatPDU *pChatPDU=makeChatPDU(iLen);
        pChatPDU->iChatPDULen=iLen;
        pChatPDU->iTYPE=ENUM_TYPE_OUT_GROUP_GO;
        pChatPDU->iFROM=g_iId;
        pChatPDU->iTO=iId;
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_iFlag==0);
        g_iFlag=0;
        return ;
    }
    //收获踢出返回
    void getPullPeopleOutGroupBack(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==0)
        {
            printf("提出失败:该用户不存在\n");
            g_iFlag=1;
        }
        else if(pChatPDU->data.ifLogin==1)
        {
            printf("踢出失败:该用户不是群成员了\n");
            g_iFlag=1;
        }
        else 
        {
            printf("踢出成功\n");
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    //踢出通知
    void getPullPeopleOutGroupSend(ChatPDU *pChatPDU)
    {
        printf("你已被管理员踢出群---%s\n",pChatPDU->caFileName);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //退出登录
    void quitEnter(int sockfd)
    {
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iTYPE=ENUM_TYPE_QUIT_ENTER_GO;
        pChatPDU->iFROM=g_iId;
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        return;
    
    }
    //退出登录通知
    void quitEnterSend(ChatPDU *pChatPDU)
    {
        printf("你的好友%s已下线\n",pChatPDU->data.caName);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //群聊界面
    void chatGroupFace(int sockfd)
    {
        while(1)
        {
            printf("01.创建群组\n");
            printf("02.拉人\n");
            printf("03.群聊\n");
            printf("04.查看群成员\n");
            printf("05.设置管理员\n");
            printf("06.上传群文件\n");
            printf("07.查看群文件\n");
            printf("08.下载群文件\n");
            printf("09.禁言\n");
            printf("10.解禁言\n");
            printf("11.踢人\n");
            printf("12.返回\n");
            int select;
            scanf("%d",&select);
            switch(select)
            {
                case 1:
                    sendSetGroup(sockfd);
                    break;
                case 2:
                    pullPeopleInGroup(sockfd);
                    break;
                case 3:
                    chatGroup(sockfd);
                    break;
                case 4:
                    sendToAskGroupUsr(sockfd);
                    break;
                case 5:
                    setAdministrator(sockfd);
                    break;
                case 6:
                    sendDataToServerFromFile(sockfd);
                    break;
                case 7:
                    sendAskFileNameFromServer(sockfd);
                    break;
                case 8:
                    sendPleaseToDownFileFromServer(sockfd);
                    break;
                case 9:
                    sendBannedToPost(sockfd);
                    break;
                case 10:
                    sendLiftBanned(sockfd);
                    break;
                case 11:
                    pullPeopleOutGroup(sockfd);
                    break;
                case 12:
                    return ;
                    break;
                default:
                    printf("输入有误\n");
                    break;
            }
        }
    
    }
    
    //用户界面
    void clientFace(int sockfd)
    {
        while(1)
        {
            printf("01.查看所有用户\n");
            printf("02.查看在线用户\n");
            printf("03.私聊\n");
            printf("04.群聊\n");
            printf("05.修改密码\n");
            printf("06.写日志\n");
            printf("07.查看某人日志\n");
            printf("08.退出登录\n");
            int select;
            scanf("%d",&select);
            switch(select)
            {
                case 1:
                    sendToAskAllUsr(sockfd);
                    break;
                case 2:
                    sendToAskOnlineUsr(sockfd);
                    break;
                case 3:
                    chatPrivate(sockfd);
                    break;
                case 4:
                    chatGroupFace(sockfd);
                    break;
                case 5:
                    sendChangePasswordPlease(sockfd);
                    return ;
                    break;
                case 6:
                    sendWriteDailyData(sockfd);
                    break;
                case 7:
                    sendReadDailyData(sockfd);
                    break;
                case 8:
                    quitEnter(sockfd);
                    return; 
                    break;
                default:
                    printf("输入有误\n");
                    break;
            }
        }
    }
    
    //发送登录请求
    void sendEnterPleaseToServer(int sockfd)
    {
        printf("请输入账号Id:");
        int iId=0;
        scanf("%d",&iId);
        printf("请输入密码password:");
        int iPass=0;
        system("stty -echo");
        scanf("%d",&iPass);
        system("stty echo");
        printf("\n");
        int iLen=sizeof(ChatPDU);
        ChatPDU *pChatPDU=makeChatPDU(iLen);
        pChatPDU->iChatPDULen=iLen;
        pChatPDU->iTYPE=ENUM_TYPE_ENTER_GO;
        pChatPDU->iFROM=iId;
        pChatPDU->iTO=SERVER;
        pChatPDU->data.iId=iId;
        pChatPDU->data.iPassword=iPass;
        sendDataToServer(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        while(g_ifOnline==2);
        if(g_ifOnline==0)
        {
            printf("登录失败\n");
            g_ifOnline=2;
            return ;
        }
        else if(g_ifOnline==1)
        {
            printf("登陆成功\n");
            g_iId=iId;
            g_ifOnline=2;
    
            clientFace(sockfd);
            return ;
        }
    }
    
    
    //收获登录返回
    void getEnterBack(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifOnline==1)
        {
            g_iPass=pChatPDU->data.iPassword;
            g_ifOnline=1;
        }
        else if(pChatPDU->data.ifOnline==0)
        {
            g_ifOnline=0;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //好友登录通知
    void getEnterSend(ChatPDU *pChatPDU)
    {
        printf("你的好友 %s 已上线\n",pChatPDU->data.caName);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //发送注册请求
    void sendLoginPleaseToServer(int sockfd)
    {
    
        Data data;
        int iLen=sizeof(ChatPDU);
        ChatPDU *pChatPDU=makeChatPDU(iLen);
        while(1)
        {
            memset(pChatPDU,0,iLen);
            data=initData(data);
            data=inputData(data);
            pChatPDU->iChatPDULen=iLen;
            pChatPDU->data=data;
            pChatPDU->iTYPE=ENUM_TYPE_LOGIN_GO;
            pChatPDU->iTO=SERVER;
            pChatPDU->iFROM=data.iId;
            printf("iId=%d\n",pChatPDU->data.iId);
            sendDataToServer(sockfd,pChatPDU);
            while(1)
            {
                while(g_iFlag==0);
                g_iFlag=0;
                printf("是否继续注册?\n");
                printf("1.是            2.否\n");
                int select;
                scanf("%d",&select);
                if(select==1)
                {
                    break;
                }
                else if(select==2)
                {
                    free(pChatPDU);
                    pChatPDU=NULL;
                    return ;
                }
                else
                {
                    printf("输入有误\n");
                }
    
            }
        }
    
    }
    //收获注册返回
    void getLoginBack(ChatPDU *pChatPDU)
    {
        if(pChatPDU->data.ifLogin==0)
        {
            printf("账号已存在,请重新注册\n");
            g_iFlag=1;
        }
        else
        {
            printf("账号注册成功\n");
            g_iFlag=1;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    
    
    
    void* readData(void *arg)
    {
        int sockfd =* (int*)arg;
        int iMsgType=0;
        ChatPDU *pChatPDU=NULL;
        while (1)
        {
            pChatPDU=readDataFromServer(sockfd);
            if(pChatPDU!=NULL)
            {
            /*解析PDU*/
                iMsgType=parsePDU(pChatPDU);
                switch(iMsgType)
                {
                    case ENUM_TYPE_LOGIN_BACK:
                        getLoginBack(pChatPDU);
                        break;
                    case ENUM_TYPE_ENTER_BACK:
                        getEnterBack(pChatPDU);
                        break;
                    case ENUM_TYPE_ENTER_SEND:
                        getEnterSend(pChatPDU);
                        break;
                    case ENUM_TYPE_ASK_ID_BACK:
                        getAskOnlineUsrBack(pChatPDU);
                        break;
                    case ENUM_TYPE_CHAT_PRICATE_BACK:
                        getChatPrivateData(pChatPDU);
                        break;
                    case ENUM_TYPE_CHAT_PRICATE_SEND:
                        chatPrivateSend(pChatPDU);
                        break;
                    case ENUM_TYPE_READ_DAILY_BACK:
                        getReadDaileData(pChatPDU);
                        break;
                    case ENUM_TYPE_ASK_ALL_ID_BACK:
                        getAskAllUsrBack(pChatPDU);
                        break;
                    case ENUM_TYPE_SET_GROUP_BACK:
                        getSetGroupBack(pChatPDU);
                        break;
                    case ENUM_TYPE_IN_GROUP_BACK:
                        getPullPeopleInGroupBack(pChatPDU);
                        break;
                    case ENUM_TYPE_IN_GROUP_SEND:
                        getPullPeopleInGroupSend(pChatPDU);
                        break;
                    case ENUM_TYPE_CHAT_GROUP_BACK:
                        getChatGroupData(pChatPDU);
                        break;
                    case ENUM_TYPE_ASK_GROUP_ID_BACK:
                        getAskGroupUsrBack(pChatPDU);
                        break;
                    case ENUM_TYPE_SET_ADMINISTRATOR_BACK:
                        getSetAdministratorBack(pChatPDU);
                        break;
                    case ENUM_TYPE_ASK_FILE_BACK:
                        getAskFileName(pChatPDU);
                        break;
                    case ENUM_TYPE_DOWN_FILE_BACK:
                        readFileFromServer(pChatPDU);
                        break;
                    case ENUM_TYPE_BANNED_TO_POST_BACK:
                        getBannedToPostBack(pChatPDU);
                        break;
                    case ENUM_TYPE_BANNED_TO_POST_SEND:
                        getBannedToPostSend(pChatPDU);
                        break;
                    case ENUM_TYPE_LIFT_BAN_BACK:
                        getLiftBannedBack(pChatPDU);
                        break;
                    case ENUM_TYPE_LIFT_BAN_SEND:
                        getLiftBannedSend(pChatPDU);
                        break;
                    case ENUM_TYPE_OUT_GROUP_BACK:
                        getPullPeopleOutGroupBack(pChatPDU);
                        break;
                    case ENUM_TYPE_OUT_GROUP_SEND:
                        getPullPeopleOutGroupSend(pChatPDU);
                        break;
                    case ENUM_TYPE_QUIT_ENTER_SEND:
                        quitEnterSend(pChatPDU);
                        break;
                    default:
                        break;
    
                }
            }
    
        }
    }
    
    
    
    void menu(int socketfd)
    {
        while(1)
        {
            system("clear");
            printf("01.注册\n");
            printf("02.登录\n");
            printf("03.退出\n");
            int select;
            scanf("%d",&select);
            switch(select)
            {
                case 1:
                    sendLoginPleaseToServer(socketfd);
                    break;
                case 2:
                    sendEnterPleaseToServer(socketfd);
                    break;
                case 3:
                    return ;
                    //exit(1);
                    break;
                default:
                    printf("输入有误\n");
                    break;
            }
        }
        return ;
    }
    
    void handle(int sig)
    {
        if(sig==SIGINT)
        {
            quitEnter(g_iSockfd);
            exit(1);
        }
    }
    
    int main(int argc,char **argv)
    {
        signal(SIGINT,handle);
        g_pHead=makeList();
        int socketfd = 0;
        //AF_INET: ipv4
        //SOCK_STREAM: tcp/ip
        socketfd = socket(AF_INET, SOCK_STREAM, 0);
        if (-1 == socketfd)
        {
            perror("socket");
            return -1;
        }
        g_iSockfd=socketfd;
        struct sockaddr_in servaddr;
        //地址协议:ipv4
        servaddr.sin_family = AF_INET;
        //服务器端口
        servaddr.sin_port = htons(atoi(argv[2]));
        //服务器ip
        servaddr.sin_addr.s_addr = inet_addr(argv[1]);
        bzero(&(servaddr.sin_zero), 8);
        int ret = connect(socketfd
                    , (struct sockaddr *)&servaddr
                    , sizeof(struct sockaddr));
        if (-1 == ret)
        {
            perror("connect");
            return -1;
        }
        
        printf("connect ok...\n");
        pthread_t pt;
    
        ret = pthread_create(&pt, NULL, readData
                             , (void *)&socketfd);
        if (0 != ret)
        {
            perror("pthread_create");
            return -1;
        }
        menu(socketfd);
        return 0;
    }
    
    

    2.server

    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    /*socket()  send()*/
    #include <sys/types.h>
    #include <sys/socket.h>
    
    #include <netinet/in.h>
    #include <unistd.h>  //fork()
    
    /*wait()*/
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <signal.h>  //signal()
    
    #include <pthread.h>  //thread
    #include "../link/node.h"
    #include "../protocol/protocol.h"
    #include "../fileLink/fileNode.h"
    #include <stdlib.h>
    
    #include <arpa/inet.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #define MAXLEN 1024        
    Head *pHead=NULL;
    fileHead *fHead=NULL;
    
    void sendDataToClient(int sockClient,ChatPDU *pChatPDU)
    {
        if(pChatPDU==NULL)
        {
            return ;
        }
        int ret=0;
        int iLen=pChatPDU->iChatPDULen;
        int iLeft=iLen;
        int iSend=0;
    
        ret=send(sockClient,pChatPDU,iLen,0);
        iLeft-=ret;
        iSend+=ret;
        while(ret>0&&iLeft)
        {
            ret=send(sockClient,(char *)pChatPDU+iSend,iLeft,0);
            iLeft-=ret;
            iSend+=ret;
    
        }
    
    }
    
    
    ChatPDU * readDataFromClient(int sockfd)
    {
        int ret=0;
        unsigned int iPDULen=0;
        ret=recv(sockfd,&iPDULen,sizeof(int),0);
        if(ret==-1)
        {
            perror("recv");
            return NULL;
        }
        else if(ret == 0)
            return NULL;
        ChatPDU *pChatPDU=(ChatPDU *)malloc(iPDULen);
        memset(pChatPDU,0,iPDULen);
        pChatPDU->iChatPDULen=iPDULen;
        int iLeft=iPDULen-ret;
        int iRecv=ret;
        while(ret>0&&iLeft)//不能保证一次性收完,循环接收
        {
            ret=recv(sockfd,(char *)pChatPDU+iRecv,iLeft,0);
            iRecv+=ret;
            iLeft-=ret;
        }
        return pChatPDU;
    }
    
    
    //保存文件链表到文件
    void saveFileNameToFile()
    {
        int fd=open("file.dat",O_WRONLY);
        fileNode *fNode=NULL;
        fNode=fHead->pFirstNode;
        while(fNode!=NULL)
        {
            write(fd,fNode,sizeof(fileNode));
            fNode=fNode->pNext;
        }
        close(fd);
        
    }
    //读取文件链表文件
    void readFileNameFromFile()
    {
        int fd=open("file.dat",O_RDONLY);
        fileNode *fNode=NULL;
        int ret=0;
        while(1)
        {
            fNode=makeFileNode();
            ret=read(fd,fNode,sizeof(fileNode));
            if(ret==0)
            {
                break;
            }
            insertFileList(fHead,fNode);            
        }
        close(fd);
    }
    
    
    //保存到文件
    void saveToFile()
    {
        int fd=open("test.dat",O_WRONLY);
        Node *pNode=NULL;
        pNode=pHead->pFirstNode;
        while(pNode!=NULL)
        {
            write(fd,pNode,sizeof(Node));
            pNode=pNode->pNext;
        }
        close(fd);
        
    }
    //读取文件
    void readFromFile()
    {
        int fd=open("test.dat",O_RDONLY);
        Node *pNode=NULL;
        int ret=0;
        while(1)
        {
            pNode=makeNode();
            ret=read(fd,pNode,sizeof(Node));
            if(ret==0)
            {
                break;
            }
            insertList(pHead,pNode);            
        }
        close(fd);
    }
    //好友登录通知
    void EnterSend(int iId)
    {
        Node *pNode1=findNode(pHead,iId);
        ChatPDU *pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        pChatPDU->iTYPE=ENUM_TYPE_ENTER_SEND;
        Node *pNode=pHead->pFirstNode;
        while(pNode!=NULL)
        {
            if(pNode->data.ifOnline==1&&pNode->data.iId!=iId)
            {
                printf("pNode->data.iId:%d---iId:%d\n",pNode->data.iId,iId);
                strcpy(pChatPDU->data.caName,pNode1->data.caName);
                sendDataToClient(pNode->sockfd,pChatPDU);
            }
            pNode=pNode->pNext;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //登录
    void getEnterPleaseFromClient(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode=NULL;
        pNode=findNode(pHead,pChatPDU->data.iId);
        pChatPDU->iTYPE=ENUM_TYPE_ENTER_BACK;
        if(pNode!=NULL)
        {
            if(pNode->data.iPassword==pChatPDU->data.iPassword)
            {
                pNode->sockfd=sockfd;
                pNode->data.ifOnline=1;
                pChatPDU->data.iPassword=pNode->data.iPassword;
                pChatPDU->data.ifOnline=1;
                sendDataToClient(sockfd,pChatPDU);
                EnterSend(pNode->data.iId);
            }
            else
            {
                sendDataToClient(sockfd,pChatPDU);
            }
        }
        else
        {
            sendDataToClient(sockfd,pChatPDU);
        }
        free(pChatPDU);
        pChatPDU=NULL;
    
    }
    
    
    
    
    
    
    //注册接收
    void getLoginpleaseFromClient(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode=NULL;
        pNode=findNode(pHead,pChatPDU->data.iId);
        pChatPDU->iTYPE=ENUM_TYPE_LOGIN_BACK;
        if(pNode==NULL)
        {
            pNode=makeNode();
            initNode(pNode,pChatPDU->data);
            insertList(pHead,pNode);
            pChatPDU->data.ifLogin=1;
    
            saveToFile();
        }
        sendDataToClient(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //收到查看所有人员请求
    void getAskToAllUsr(int sockfd)
    {
        ChatPDU *pChatPDU=NULL;
        pChatPDU=makeChatPDU(sizeof(ChatPDU));
        Node *pNode=NULL;
        pNode=pHead->pFirstNode;
        while(pNode!=NULL)
        {
            memset(pChatPDU,0,sizeof(ChatPDU));
            pChatPDU->data=pNode->data;
            pChatPDU->iTYPE=ENUM_TYPE_ASK_ALL_ID_BACK;
            pChatPDU->iChatPDULen=sizeof(ChatPDU);
            if(pNode->pNext==NULL)
            {
                pChatPDU->data.ifOnline=0;
            }
            sendDataToClient(sockfd,pChatPDU);
            pNode=pNode->pNext;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //收到查看在线人员请求
    void getAskToOnlineUsr(int sockfd)
    {
        ChatPDU *pChatPDU=NULL;
        pChatPDU=makeChatPDU(sizeof(ChatPDU));
        //memset(pChatPDU,0,sizeof(ChatPDU));
        Node *pNode=NULL;
        pNode=pHead->pFirstNode;
        pChatPDU->iTYPE=ENUM_TYPE_ASK_ID_BACK;
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        while(pNode!=NULL)
        {
            if(pNode->data.ifOnline==1)
            {
                pChatPDU->data=pNode->data;
                pChatPDU->data.ifLogin=0;
                sendDataToClient(sockfd,pChatPDU);
            }
            pNode=pNode->pNext;
        }
        pChatPDU->data.ifLogin=1;
        sendDataToClient(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //私聊
    void chatPrivateToClient(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode=findNode(pHead,pChatPDU->iFROM);
        strcpy(pChatPDU->data.caName,pNode->data.caName);
        pChatPDU->iTYPE=ENUM_TYPE_CHAT_PRICATE_BACK;
        pNode=findNode(pHead,pChatPDU->iTO);
        if(pNode->data.ifOnline==0)
        {
            pChatPDU->iTYPE=ENUM_TYPE_CHAT_PRICATE_SEND;
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return;
        }
        sendDataToClient(pNode->sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //修改密码
    void changePassword(ChatPDU *pChatPDU)
    {
        Node *pNode=NULL;
        pNode=findNode(pHead,pChatPDU->iFROM);
        pNode->data.iPassword=pChatPDU->data.iPassword;
        saveToFile();
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    #if 1
    //写日志
    void writeDaily(ChatPDU *pChatPDU)
    {
        Node *pNode=NULL;
        pNode=findNode(pHead,pChatPDU->iFROM);
        strcpy(pNode->caDaily,pChatPDU->chatData);
        saveToFile();
        free(pChatPDU);
        pChatPDU=NULL;
    }
    //查看某人日志
    void readDaily(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode=NULL;
        pNode=findNode(pHead,pChatPDU->iTO);
        free(pChatPDU);
        pChatPDU=NULL;
        int iLen=sizeof(ChatPDU)-sizeof(int)+strlen(pNode->caDaily)+1;
        pChatPDU=makeChatPDU(iLen);
        pChatPDU->iChatPDULen=iLen;
        strcpy(pChatPDU->chatData,pNode->caDaily);
        strcpy(pChatPDU->data.caName,pNode->data.caName);
        pChatPDU->iTYPE=ENUM_TYPE_READ_DAILY_BACK;
        sendDataToClient(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        
    }
    #endif
    //创建群组
    void setChatGroup(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode=NULL;
        pNode=pHead->pFirstNode;
        pChatPDU->iTYPE=ENUM_TYPE_SET_GROUP_BACK;
        while(pNode!=NULL)
        {
            if(strcmp(pNode->caGroupName,pChatPDU->chatData)==0)
            {           
                sendDataToClient(sockfd,pChatPDU);
                free(pChatPDU);
                pChatPDU=NULL;
                return;
            }
            pNode=pNode->pNext;
        }
        pNode=findNode(pHead,pChatPDU->iFROM);
        strcpy(pNode->caGroupName,pChatPDU->chatData);
        pNode->iStatus=GROUP_GANAPATI;  
        saveToFile();
        pChatPDU->data.ifLogin=1;
        sendDataToClient(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    #if 1
    //拉人
    void pullPeopleInGroup(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode=findNode(pHead,pChatPDU->iFROM);
        Node *pNode1=findNode(pHead,pChatPDU->iTO); 
        pChatPDU->iTYPE=ENUM_TYPE_IN_GROUP_BACK;
        if(pNode1==NULL)
        {
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
        else
        {
            if(strcmp(pNode1->caGroupName,pNode->caGroupName)==0)
            {
                pChatPDU->data.ifLogin=1;
                sendDataToClient(sockfd,pChatPDU);
                free(pChatPDU);
                pChatPDU=NULL;
                return ;    
            }
            strcpy(pNode1->caGroupName,pNode->caGroupName);
            saveToFile();
            pChatPDU->data.ifLogin=2;
            sendDataToClient(sockfd,pChatPDU);
            pChatPDU->iTYPE=ENUM_TYPE_IN_GROUP_SEND;
            strcpy(pChatPDU->caFileName,pNode->caGroupName);
            sendDataToClient(pNode1->sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
    }
    #endif
    
    //群聊
    void chatGroupToClient(int sockfd,ChatPDU *pChatPDU)
    {
    
        int sockfd1=0;
        Node *pNode1=findNode(pHead,pChatPDU->iFROM);
        if(pNode1->iIfBanned==1)//禁言
        {
            pChatPDU->data.ifLogin=3;
            pChatPDU->iTYPE=ENUM_TYPE_BANNED_TO_POST_SEND;
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
        else if(strcmp(pNode1->caGroupName,"\0")==0)//未加入群组
        {
            pChatPDU->data.ifLogin=4;
            pChatPDU->iTYPE=ENUM_TYPE_BANNED_TO_POST_SEND;
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;    
        }
        Node *pNode=pHead->pFirstNode;
        pChatPDU->iTYPE=ENUM_TYPE_CHAT_PRICATE_BACK;
        while(pNode!=NULL)
        {
            if(pNode->data.ifOnline==1 && strcmp(pNode->caGroupName,pNode1->caGroupName)==0 && pNode->data.iId!=pNode1->data.iId)
            {
                sockfd1=pNode->sockfd;
                strcpy(pChatPDU->data.caName,pNode1->data.caName);
                sendDataToClient(sockfd1,pChatPDU);
            }
            pNode=pNode->pNext;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //收到查看群成员请求
    void getAskToGroupUsr(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode1=findNode(pHead,pChatPDU->iFROM);
        free(pChatPDU);
        pChatPDU=NULL;
        pChatPDU=makeChatPDU(sizeof(ChatPDU));
        pChatPDU->iTYPE=ENUM_TYPE_ASK_GROUP_ID_BACK;
        pChatPDU->iChatPDULen=sizeof(ChatPDU);
        Node *pNode=NULL;
        pNode=pHead->pFirstNode;
        while(pNode!=NULL)
        {
            if(strcmp(pNode->caGroupName,pNode1->caGroupName)==0)
            {
                pChatPDU->data=pNode->data;
                pChatPDU->data.ifLogin=0;
                sendDataToClient(sockfd,pChatPDU);
            }
            pNode=pNode->pNext;
        }
        pChatPDU->data.ifLogin=1;
        sendDataToClient(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    
    //设置管理员
    void setAdministrtor(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode=findNode(pHead,pChatPDU->iFROM);
        Node *pNode1=findNode(pHead,pChatPDU->iTO); 
        pChatPDU->iTYPE=ENUM_TYPE_SET_ADMINISTRATOR_BACK;
        if(pNode->iStatus!=GROUP_GANAPATI&&pNode->iStatus!=GROUP_ADMINISTRATOR)
        {
            pChatPDU->data.ifLogin=3;
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
            
        }
        if(pNode1==NULL||strcmp(pNode1->caGroupName,pNode->caGroupName)!=0)
        {
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
        else
        {
            if(pNode1->iStatus==GROUP_ADMINISTRATOR||pNode1->iStatus==GROUP_GANAPATI)
            {
                pChatPDU->data.ifLogin=1;
                sendDataToClient(sockfd,pChatPDU);
                free(pChatPDU);
                pChatPDU=NULL;
                return ;
            
            }
            pNode1->iStatus=GROUP_ADMINISTRATOR;
            saveToFile();
            pChatPDU->data.ifLogin=2;
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
    
    
    }
    
    
    //从客户端接收文件
    void readFileFromClient(ChatPDU *pChatPDU)
    {
        char caFileName[64]={'\0'};
        strcpy(caFileName,pChatPDU->caFileName);
        fileNode *fNode=makeFileNode();
        initFileNode(fNode,caFileName);
        insertFileList(fHead,fNode);
        saveFileNameToFile();
    
        printf("chadata:%s",pChatPDU->chatData);    
        FILE *fd=fopen(caFileName,"w");
        if(fd==NULL)
        {
            perror("fopen");
            return ;
        }
        int iLen=pChatPDU->iChatDataLen;
        printf("iLen:%d",iLen);
        fprintf(fd,"%s",pChatPDU->chatData);
        fclose(fd);
        printf("上传成功\n");
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //查看文件链表
    void AskFileName(int sockfd,ChatPDU *pChatPDU)
    {
        
        pChatPDU->iTYPE=ENUM_TYPE_ASK_FILE_BACK;
        if(fHead==NULL)
        {
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
    
        }
        fileNode *fNode=fHead->pFirstNode;
        while(fNode!=NULL)
        {
            strcpy(pChatPDU->data.caName,fNode->caFileName);
            if(fNode->pNext==NULL)
            {
                pChatPDU->data.ifLogin=1;
            }
            sendDataToClient(sockfd,pChatPDU);  
            fNode=fNode->pNext;
    
        }
        free(pChatPDU);
        pChatPDU=NULL;
        return ;
    }
    
    
    
    //发送文件到客户端
    void sendFileToClient(int sockfd,ChatPDU *pChatPDU)
    {
        
        char caFileNAME[64]={'\0'};
        strcpy(caFileNAME,pChatPDU->caFileName);
        int fd=open(caFileNAME,O_RDONLY);
        if(fd==-1)
        {
            perror("open");
            return ;
        }
        int iLen=lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);
        int iLeft=iLen;
        char caBuf[MAXLEN]={'\0'};
        int iRead=0;
        int ret=read(fd,caBuf,iLeft);
        while(ret>0 && iLeft)
        {
            ret=read(fd,caBuf,iLeft);
            iLeft-=ret;
            iRead+=ret;     
        }
        free(pChatPDU);
        pChatPDU=NULL;
        pChatPDU=(ChatPDU *)malloc(sizeof(ChatPDU)-sizeof(int)+iLen);
        pChatPDU->iTYPE=ENUM_TYPE_DOWN_FILE_BACK;
        pChatPDU->iFROM=SERVER;
        strcpy(pChatPDU->caFileName,caFileNAME);
        pChatPDU->iChatDataLen=iLen;
        pChatPDU->iChatPDULen=sizeof(ChatPDU)-sizeof(int)+iLen;
        strcpy(pChatPDU->chatData,caBuf);
        sendDataToClient(sockfd,pChatPDU);
        free(pChatPDU);
        pChatPDU=NULL;
        
    }
    //禁言
    void bannedToPost(int sockfd,ChatPDU *pChatPDU)
    {
        pChatPDU->iTYPE=ENUM_TYPE_BANNED_TO_POST_BACK;
        Node *pNode=findNode(pHead,pChatPDU->iFROM);
        Node *pNode1=NULL;
        if(strcmp(pNode->caGroupName,"\0")==0)//未加入群组
        {
            pChatPDU->data.ifLogin=0;
            sendDataToClient(sockfd,pChatPDU);      
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
        else if(pNode->iStatus==GROUP_CREW)//权限不足
        {
            pChatPDU->data.ifLogin=1;
            sendDataToClient(sockfd,pChatPDU);      
            free(pChatPDU);
            pChatPDU=NULL;
            return ;        
        }
        else if(pChatPDU->iTO==0)//全员禁言
        {
            pNode1=pHead->pFirstNode;
            while(pNode1!=NULL)
            {
                if(strcmp(pNode->caGroupName,pNode1->caGroupName)==0)
                {
                    pNode1->iIfBanned=1;
                    if(pNode1->data.ifLogin==1&&pNode->data.iId!=pNode1->data.iId)
                    {
                        
                        pChatPDU->data.ifLogin=2;
                        pChatPDU->iTYPE=ENUM_TYPE_BANNED_TO_POST_SEND;
                        sendDataToClient(pNode1->sockfd,pChatPDU);
                    }
                }
                pNode1=pNode1->pNext;
            }
            pChatPDU->data.ifLogin=2;
            sendDataToClient(sockfd,pChatPDU);      
            free(pChatPDU);
            pChatPDU=NULL;
            saveToFile();
            return ;        
        }
        else
        {
            pNode1=findNode(pHead,pChatPDU->iTO);
            if(pNode1==NULL)//用户不存在
            {
                pChatPDU->data.ifLogin=3;
                sendDataToClient(sockfd,pChatPDU);      
                free(pChatPDU);
                pChatPDU=NULL;
                return ;                    
            }
            else
            {
                if(pNode1->iIfBanned==1)//已经被禁言
                {
                    pChatPDU->data.ifLogin=4;
                    sendDataToClient(sockfd,pChatPDU);      
                    free(pChatPDU);
                    pChatPDU=NULL;
                    return ;                    
                }
                else    //禁言成功
                {
                    pNode1->iIfBanned=1;
                    pChatPDU->data.ifLogin=5;
                    sendDataToClient(sockfd,pChatPDU);      
                    pChatPDU->iTYPE=ENUM_TYPE_BANNED_TO_POST_SEND;
                    sendDataToClient(pNode1->sockfd,pChatPDU);
                    free(pChatPDU);
                    pChatPDU=NULL;
                    saveToFile();
                    return ;                    
    
                }
            }
        }
    }
    
    //解禁言
    void liftBanned(int sockfd,ChatPDU *pChatPDU)
    {
        pChatPDU->iTYPE=ENUM_TYPE_LIFT_BAN_BACK;
        Node *pNode=findNode(pHead,pChatPDU->iFROM);
        Node *pNode1=NULL;
        if(strcmp(pNode->caGroupName,"\0")==0)//未加入群组
        {
            pChatPDU->data.ifLogin=0;
            sendDataToClient(sockfd,pChatPDU);      
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
        else if(pNode->iStatus==GROUP_CREW)//权限不足
        {
            pChatPDU->data.ifLogin=1;
            sendDataToClient(sockfd,pChatPDU);      
            free(pChatPDU);
            pChatPDU=NULL;
            return ;        
        }
        else if(pChatPDU->iTO==0)//全员解禁言
        {
            pNode1=pHead->pFirstNode;
            while(pNode1!=NULL)
            {
                if(strcmp(pNode->caGroupName,pNode1->caGroupName)==0)
                {
                    pNode1->iIfBanned=0;
                    if(pNode1->data.ifLogin==1&&pNode->data.iId!=pNode1->data.iId)
                    {
                        
                        pChatPDU->data.ifLogin=2;
                        pChatPDU->iTYPE=ENUM_TYPE_LIFT_BAN_SEND;
                        sendDataToClient(pNode1->sockfd,pChatPDU);
                    }
                }
                pNode1=pNode1->pNext;
            }
            pChatPDU->data.ifLogin=2;
            sendDataToClient(sockfd,pChatPDU);      
            free(pChatPDU);
            pChatPDU=NULL;
            saveToFile();
            return ;        
        }
        else
        {
            pNode1=findNode(pHead,pChatPDU->iTO);
            if(pNode1==NULL)//用户不存在
            {
                pChatPDU->data.ifLogin=3;
                sendDataToClient(sockfd,pChatPDU);      
                free(pChatPDU);
                pChatPDU=NULL;
                return ;                    
            }
            else
            {
                if(pNode1->iIfBanned==0)//未被禁言,无需解禁
                {
                    pChatPDU->data.ifLogin=4;
                    sendDataToClient(sockfd,pChatPDU);      
                    free(pChatPDU);
                    pChatPDU=NULL;
                    return ;                    
                }
                else    //解禁言成功
                {
                    pNode1->iIfBanned=0;
                    pChatPDU->data.ifLogin=5;
                    sendDataToClient(sockfd,pChatPDU);      
                    pChatPDU->iTYPE=ENUM_TYPE_LIFT_BAN_SEND;
                    sendDataToClient(pNode1->sockfd,pChatPDU);
                    free(pChatPDU);
                    pChatPDU=NULL;
                    saveToFile();
                    return ;                    
    
                }
            }
        }
    }
    
    
    //踢人
    void pullPeopleOutGroup(int sockfd,ChatPDU *pChatPDU)
    {
        Node *pNode=findNode(pHead,pChatPDU->iFROM);
        Node *pNode1=findNode(pHead,pChatPDU->iTO); 
        pChatPDU->iTYPE=ENUM_TYPE_OUT_GROUP_BACK;
        if(pNode1==NULL)//用户不存在
        {
            sendDataToClient(sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
        else
        {
            if(strcmp(pNode1->caGroupName,pNode->caGroupName)!=0)//用户非本群成员
            {
                pChatPDU->data.ifLogin=1;
                sendDataToClient(sockfd,pChatPDU);
                free(pChatPDU);
                pChatPDU=NULL;
                return ;    
            }
            strcpy(pNode1->caGroupName,"\0");
            saveToFile();
            pChatPDU->data.ifLogin=2;
            sendDataToClient(sockfd,pChatPDU);
            pChatPDU->iTYPE=ENUM_TYPE_OUT_GROUP_SEND;
            strcpy(pChatPDU->caFileName,pNode->caGroupName);
            sendDataToClient(pNode1->sockfd,pChatPDU);
            free(pChatPDU);
            pChatPDU=NULL;
            return ;
        }
    }
    
    //退出登录
    void quitEnter(ChatPDU *pChatPDU)
    {
        Node *pNode=findNode(pHead,pChatPDU->iFROM);
        pNode->data.ifOnline=0;
        pNode->sockfd=0;
        saveToFile();
        strcpy(pChatPDU->data.caName,pNode->data.caName);
        pChatPDU->iTYPE=ENUM_TYPE_QUIT_ENTER_SEND;
        pNode=pHead->pFirstNode;
        while(pNode!=NULL)
        {
            if(pNode->data.ifOnline==1)
            {
                sendDataToClient(pNode->sockfd,pChatPDU);           
            }
            pNode=pNode->pNext;
        }
        free(pChatPDU);
        pChatPDU=NULL;
    }
    
    //线程
    void *handleClient(void *arg)
    {
        int sockClient = *(int*)arg;
        ChatPDU *pChatPDU=NULL;
        int iMsgType=0;
        while (1)
        {
            //获得PDU
            pChatPDU=readDataFromClient(sockClient);
            if(pChatPDU!=NULL)
            {
            /*解析PDU*/
                iMsgType=parsePDU(pChatPDU);
                switch(iMsgType)
                {
                    case ENUM_TYPE_LOGIN_GO:
                        getLoginpleaseFromClient(sockClient,pChatPDU);
                        showList(pHead);
                        break;
                    case ENUM_TYPE_ENTER_GO:
                        getEnterPleaseFromClient(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_ASK_ID_GO:
                        getAskToOnlineUsr(sockClient);
                        break;
                    case ENUM_TYPE_ASK_ALL_ID_GO:
                        getAskToAllUsr(sockClient);
                        break;
                    case ENUM_TYPE_CHAT_PRICATE_GO:
                        chatPrivateToClient(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_CHANGE_PASSWORD_GO:
                        changePassword(pChatPDU);
                        break;
                    case ENUM_TYPE_WRITE_DAILY_GO:
                        writeDaily(pChatPDU);
                        break;
                    case ENUM_TYPE_READ_DAILY_GO:
                        readDaily(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_SET_GROUP_GO:
                        setChatGroup(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_IN_GROUP_GO:
                        pullPeopleInGroup(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_CHAT_GROUP_GO:
                        chatGroupToClient(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_ASK_GROUP_ID_GO:
                        getAskToGroupUsr(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_SET_ADMINISTRATOR_GO:
                        setAdministrtor(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_UP_FILE:
                        readFileFromClient(pChatPDU);
                        break;
                    case ENUM_TYPE_ASK_FILE_GO:
                        AskFileName(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_DOWN_FILE_GO:
                        sendFileToClient(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_BANNED_TO_POST_GO:
                        bannedToPost(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_LIFT_BAN_GO:
                        liftBanned(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_OUT_GROUP_GO:
                        pullPeopleOutGroup(sockClient,pChatPDU);
                        break;
                    case ENUM_TYPE_QUIT_ENTER_GO:
                        quitEnter(pChatPDU);
                        break;
                    default:
                        break;
    
                }
            }
            else
                return NULL;
        
        }
    }
    
    int main(int argc,char **argv)
    {
        pHead=makeList();
        fHead=makeFileList();
        readFromFile();
        showList(pHead);
        readFileNameFromFile();
        
    
        int sockfd = 0;
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (-1 == sockfd)
        {
            perror("socket");
            return -1;
        }
        struct sockaddr_in servaddr;
        //地址协议:ipv4
        servaddr.sin_family = AF_INET;
        //服务器端口
        servaddr.sin_port = htons(atoi(argv[2]));
        //服务器ip
        servaddr.sin_addr.s_addr = inet_addr(argv[1]);
        bzero(&(servaddr.sin_zero), 8);
        int ret = bind(sockfd
                       , (struct sockaddr *)&servaddr
                       , sizeof(struct sockaddr));
        if (-1 == ret)
        {
            perror("bind");
            return -1;
        }
        ret = listen(sockfd, 10);
        if (-1 == ret)
        {
            perror("listen");
            return -1;
        }
    
        struct sockaddr_in clientaddr;
        int iLen = sizeof(struct sockaddr);
        int sockClient = 0;
        pthread_t pt;
        while (1)
        {
            printf("accepting client connect...\n");
            sockClient = accept(sockfd
                        , (struct sockaddr *)&clientaddr
                        ,(socklen_t *)&iLen);
            
            ret = pthread_create(&pt, NULL, handleClient
                                 , (void *)&sockClient);
            if (0 != ret)
            {
                perror("pthread_create");
                return -1;
            }
        }
        pthread_detach(pt);
    
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:“掌中”通讯

          本文链接:https://www.haomeiwen.com/subject/eosmgttx.html