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;
}