#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 9000
#define BUFF_SIZE 1024
int ERROR;
struct user
{
int socketfd;
int toSocketfd;
char name[20];
char toName[20];
char msg[100];
int result;
int cmd;
int nrow;
int ncolumn;
char resultp[40][20];
char catalogue[20][20];
int num;
int vip[20];
int silence[20];
};
struct userManage
{
int flag[20];
int silence[20];
int vip[20];
struct user users[20];
};
struct userManage uMge;
pthread_mutex_t mutex;
void Initsystem()
{
ERROR = 0;
int i;
int fd;
printf("正在初始化用户管理\n");
memset(&uMge, 0, sizeof(uMge));
for(i = 0; i<20; i++)
{
uMge.flag[i] = 0;
uMge.silence[i] = 0;
uMge.vip[i] = 0;
}
printf("正在初始化聊天记录\n");
fd = open("Server_log.txt", O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IXUSR);
if (-1 == fd)
{
perror("open bb.c");
}
close(fd);
printf("正在检查数据库文件\n");
fd = open("chatroom.db", O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IXUSR);
if (-1 == fd)
{
perror("open bb.c");
}
close(fd);
char buff[200];
sqlite3 * db = NULL;
char *errmsg;
char **resultp = NULL;
int nrow, ncolumn;
int ret = sqlite3_open("chatroom.db", &db);
if (ret != SQLITE_OK)
{
printf ("open chatroom.db error!\n");
}
ret = sqlite3_exec(db, "create table if not exists student(name TEXT, passward TEXT, vip INTEGER, primary key(name))", NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("create fail:%d(%s)\n", ret ,errmsg);
}
printf("初始化vip账户CZH 密码123\n");
ret = sqlite3_get_table(db, "select name,passward,vip from student where name = 'CZH'", &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("select student table error : %d(%s)!\n", ret, errmsg);
ERROR = -2;
printf("ERROR = %d\n", ERROR);
}
if(nrow == 0)
{
ret = sqlite3_exec(db, "insert into student values('CZH', '123', 1)", NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("insert student table error : %d(%s)!\n", ret, errmsg);
}
else
{
printf("vip账户注册成功\n");
}
}
else
{
printf("vip账户已存在\n");
}
sqlite3_close(db);
printf("服务器初始化完成\n");
}
void Register(int socket_fd, struct user * userInfo)
{
printf("#1\n");
sqlite3 * db = NULL;
char *errmsg;
char **resultp = NULL;
int nrow, ncolumn;
int i;
char buff[200];
int result = sqlite3_open("chatroom.db", &db);
if (result != SQLITE_OK)
{
printf ("open chatroom.db error!\n");
ERROR = -1;
printf("ERROR = %d\n", ERROR);
}
sprintf (buff, "select name,passward,vip from student where name = '%s'", userInfo->name);
result = sqlite3_get_table(db, buff, &resultp, &nrow, &ncolumn, &errmsg);
if (result != SQLITE_OK)
{
printf ("select student table error : %d(%s)!\n", result, errmsg);
ERROR = -2;
printf("ERROR = %d\n", ERROR);
}
if(nrow == 0)
{
printf("添加新用户:%s\n",userInfo->name);
printf("用户密码:%s\n",userInfo->msg);
sprintf (buff, "insert into student values('%s', '%s', 0)", userInfo->name, userInfo->msg);
result = sqlite3_exec(db, buff, NULL, NULL, &errmsg);
if (result != SQLITE_OK)
{
printf ("insert student table error : %d(%s)!\n", result, errmsg);
ERROR = -3;
printf("ERROR = %d\n", ERROR);
}
for (i = 0; i < 20; i++)
{
if (uMge.flag[i] == 1)
{
continue;
}
uMge.users[i].socketfd = socket_fd;
strcpy(uMge.users[i].name, userInfo->name);
userInfo->result = 11;
uMge.flag[i] = 1;
break;
}
}
else
{
printf("用户注册失败\n");
userInfo->result = 10;
}
result = sqlite3_get_table(db, "select * from student", &resultp, &nrow, &ncolumn, &errmsg);
if (result != SQLITE_OK)
{
printf ("select student table error : %d(%s)!\n", result, errmsg);
ERROR = -4;
printf("ERROR = %d\n", ERROR);
}
int count = 0;
for (i = 0; i < (nrow+1)*ncolumn; i++)
{
count++;
printf ("%8s ", resultp[i]);
if (count % ncolumn == 0)
{
printf ("\n");
}
}
printf ("\n");
sqlite3_close(db);
}
void Load(int socket_fd, struct user * userInfo)
{
printf ("#2\n");
sqlite3 * db = NULL;
char *errmsg;
char **resultp = NULL;
int nrow, ncolumn;
char buff[200];
int i;
int vip = 0;
int result = sqlite3_open("chatroom.db", &db);
if (result != SQLITE_OK)
{
printf ("1open chatroom.db error!\n");
ERROR = -5;
printf("ERROR = %d\n", ERROR);
}
sprintf (buff, "select passward from student where name='%s'", userInfo->name);
result = sqlite3_get_table(db, buff, &resultp, &nrow, &ncolumn, &errmsg);
if (result != SQLITE_OK)
{
printf ("select student table error : %d(%s)!\n", result, errmsg);
ERROR = -7;
printf("ERROR = %d\n", ERROR);
}
if(nrow == 0)
{
printf("该用户不存在\n");
printf ("%s\n", userInfo->name);
userInfo->result = 20;
}
else
{
printf("验证用户密码\n");
if(!strcmp(userInfo->msg, resultp[ncolumn]))
{
printf("密码正确\n");
for (i = 0; i < 20; i++)
{
if(uMge.flag[i] == 1)
{
if(strcmp(uMge.users[i].name, userInfo->name) == 0 && uMge.users[i].socketfd !=userInfo->socketfd)
{
printf("检测到用户:%s重复登录\n默认强制登录\n");
userInfo->toSocketfd = uMge.users[i].socketfd;
uMge.users[i].socketfd = userInfo->socketfd;
userInfo->result = 22;
break;
}
}
}
if(userInfo->result != 22)
{
sprintf (buff, "select vip from student where name='%s'", userInfo->name);
result = sqlite3_get_table(db, buff, &resultp, &nrow, &ncolumn, &errmsg);
if (result != SQLITE_OK)
{
printf ("select vip student table error : %d(%s)!\n", result, errmsg);
}
if(resultp[ncolumn][0] == '1')
{
printf("检测到vip账户登录\n");
vip = 1;
}
for (i = 0; i < 20; i++)
{
if (uMge.flag[i] == 1)
{
continue;
}
uMge.users[i].socketfd = socket_fd;
strcpy(uMge.users[i].name, userInfo->name);
uMge.flag[i] = 1;
if(vip)
{
userInfo->result = 23;
printf ("vip账户%s 登录成功", uMge.users[i].name);
uMge.vip[i] = 1;
break;
}
else
{
userInfo->result = 21;
printf ("账户%s 登录成功\n", uMge.users[i].name);
break;
}
}
printf ("%s 上线了!\n", uMge.users[i].name);
}
}
else
{
printf("密码错误\n");
userInfo->result = 20;
}
}
sqlite3_close(db);
}
void Send_alone(int socket_fd, struct user * userInfo)
{
printf ("#3\n");
int i;
int silence;
for(i = 0; i < 20; i++)
{
if (uMge.flag[i] == 1)
{
printf("%d %s \n",uMge.users[i].socketfd,uMge.users[i].name);
}
}
for(i = 0; i < 20; i++)
{
if( uMge.flag[i]== 0)
{
continue;
}
if(strcmp(uMge.users[i].name, userInfo->name) == 0)
{
if(uMge.silence[i] == 1)
{
silence = 1;
}
else
{
silence = 0;
}
}
}
if(silence)
{
userInfo->result = 35;
}
else
{
for (i = 0; i < 20; i++)
{
if (uMge.flag[i] == 1)
{
if(strcmp(uMge.users[i].name, userInfo->toName) == 0)
{
if(strcmp(uMge.users[i].name, userInfo->name) == 0)
{
userInfo->result = 33;
break;
}
else
{
userInfo->toSocketfd = uMge.users[i].socketfd;
userInfo->result = 34;
break;
}
}
}
}
if(userInfo->result != 34 && userInfo->result != 33)
{
userInfo->result = 30;
}
}
}
void Broadcast(int socket_fd, struct user * userInfo)
{
printf ("#4\n");
int i;
int silence;
for(i = 0; i < 20; i++)
{
if( uMge.flag[i]== 0)
{
continue;
}
if(strcmp(uMge.users[i].name, userInfo->name) == 0)
{
if(uMge.silence[i] == 1)
{
silence = 1;
}
else
{
silence = 0;
}
break;
}
}
if(silence)
{
userInfo->result = 45;
}
else
{
userInfo->result = 44;
}
}
void Check_sqlite(int socket_fd, struct user * userInfo)
{
printf ("#5\n");
sqlite3 * db = NULL;
char *errmsg;
char **resultp = NULL;
int nrow, ncolumn;
int i;
char buff[200];
int result = sqlite3_open("chatroom.db", &db);
if (result != SQLITE_OK)
{
printf ("open chatroom.db error!\n");
ERROR = -1;
printf("ERROR = %d\n", ERROR);
}
result = sqlite3_get_table(db, "select name,vip from student", &resultp, &nrow, &ncolumn, &errmsg);
if (result != SQLITE_OK)
{
printf ("select student table error : %d(%s)!\n", result, errmsg);
printf("ERROR = %d\n", ERROR);
}
for (i = ncolumn; i < (nrow+1)*ncolumn; i++)
{
strcpy(userInfo->resultp[i - ncolumn],resultp[i]);
printf ("%8s \n", userInfo->resultp[i - ncolumn]);
}
userInfo->nrow = nrow;
userInfo->ncolumn = ncolumn;
userInfo->result = 51;
}
void Check_uMge(int socket_fd, struct user * userInfo)
{
printf ("#6\n");
int i;
int j;
j = 0;
printf("\n");
for(i = 0; i < 20; i++)
{
if (uMge.flag[i] == 1)
{
strcpy(userInfo->catalogue[j],uMge.users[i].name);
userInfo->vip[j] = uMge.vip[i];
userInfo->silence[j] = uMge.silence[i];
j++;
}
}
userInfo->result = 61;
userInfo->num = j;
}
void Kick(int socket_fd, struct user * userInfo)
{
printf ("#7\n");
int i;
int vip;
for(i = 0; i < 20; i++)
{
if( uMge.flag[i]== 0)
{
continue;
}
if(strcmp(uMge.users[i].name, userInfo->name) == 0)
{
if(uMge.vip[i] == 1)
{
vip = 1;
}
else
{
vip = 0;
}
}
}
if(vip)
{
for(i = 0; i < 20; i++)
{
if (uMge.flag[i] == 1)
{
if(strcmp(uMge.users[i].name, userInfo->toName) == 0)
{
if(strcmp(uMge.users[i].name, userInfo->name) == 0)
{
userInfo->result = 73;
break;
}
else
{
userInfo->toSocketfd = uMge.users[i].socketfd;
uMge.flag[i] = 0;
userInfo->result = 74;
break;
}
}
}
}
if(userInfo->result != 74 && userInfo->result != 73)
{
userInfo->result = 70;
}
}
else
{
userInfo->result = 100;
}
}
void Silence(int socket_fd, struct user * userInfo)
{
printf ("#8\n");
int i;
int vip;
for(i = 0; i < 20; i++)
{
if( uMge.flag[i]== 0)
{
continue;
}
if(strcmp(uMge.users[i].name, userInfo->name) == 0)
{
if(uMge.vip[i] == 1)
{
vip = 1;
}
else
{
vip = 0;
}
}
}
if(vip)
{
for(i = 0; i < 20; i++)
{
if (uMge.flag[i] == 1)
{
if(strcmp(uMge.users[i].name, userInfo->toName) == 0)
{
if(strcmp(uMge.users[i].name, userInfo->name) == 0)
{
userInfo->result = 83;
break;
}
else
{
uMge.silence[i] = 1;
userInfo->toSocketfd = uMge.users[i].socketfd;
userInfo->result = 84;
break;
}
}
}
}
if(userInfo->result != 84 && userInfo->result != 83)
{
userInfo->result = 80;
}
}
else
{
userInfo->result = 100;
}
}
void Offline(int socket_fd, struct user * userInfo)
{
printf ("#9\n");
int i;
for (i = 0; i < 20; i++)
{
if (uMge.flag[i] == 0)
{
continue;
}
if(strcmp(uMge.users[i].name, userInfo->name) == 0)
{
printf("用户%s下线\n");
uMge.flag[i] = 0;
uMge.silence[i] = 0;
uMge.vip[i] = 0;
userInfo->result = 91;
break;
}
}
}
void *server_request(int cfd)
{
int readSize, writeSize;
struct user userInfo;
int i;
int fd;
int ret;
char buf[201] = {0};
while (readSize = read(cfd, &userInfo, sizeof(userInfo)))
{
if (readSize == -1)
{
perror("read");
return ;
}
printf("收到用户%s的cmd:%d\n",userInfo.name,userInfo.cmd);
switch(userInfo.cmd)
{
case 1:
{
Register(cfd, &userInfo);
break;
}
case 2:
{
Load(cfd, &userInfo);
break;
}
case 3:
{
Send_alone(cfd, &userInfo);
break;
}
case 4:
{
Broadcast(cfd, &userInfo);
break;
}
case 5:
{
Check_sqlite(cfd, &userInfo);
break;
}
case 6:
{
Check_uMge(cfd, &userInfo);
break;
}
case 7:
{
Kick(cfd, &userInfo);
break;
}
case 8:
{
Silence(cfd, &userInfo);
break;
}
case 9:
{
Offline(cfd, &userInfo);
break;
}
default :
{
printf("错误 收到客户端cmd:%d", userInfo.cmd);
break;
}
}
printf("result:%d\n",userInfo.result);
switch(userInfo.result)
{
case 10:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 11:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 20:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 21:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 22:
{
userInfo.result = 21;
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
userInfo.result = 92;
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(userInfo.toSocketfd, &userInfo, sizeof(userInfo));
break;
}
case 23:
{
printf("向vip用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 30:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 33:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 34:
{
userInfo.result = 32;
printf("向用户%s发送result:%d\n",userInfo.toName,userInfo.result);
printf("用户%s向用户%s发送一条信息:%s\n", userInfo.name, userInfo.toName, userInfo.msg);
fd = open("Server_log.txt", O_RDWR | O_APPEND , S_IWUSR | S_IRUSR | S_IXUSR);
if (-1 == fd)
{
perror("Server_log.txt");
}
sprintf(buf, "%s(私聊) send to %s: %s",userInfo.name,userInfo.toName,userInfo.msg);
ret = write(fd, buf, 200);
if (-1 == ret)
{
perror("write");
}
close(fd);
writeSize = write(userInfo.toSocketfd, &userInfo, sizeof(userInfo));
userInfo.result = 31;
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 35:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
printf("用户%s被禁言 发送消息失败\n", userInfo.name);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 44:
{
printf("用户%s发送一条群消息:%s\n", userInfo.name, userInfo.msg);
fd = open("Server_log.txt", O_RDWR | O_APPEND , S_IWUSR | S_IRUSR | S_IXUSR);
if (-1 == fd)
{
perror("Server_log.txt");
}
sprintf(buf, "%s(群消息): %s",userInfo.name,userInfo.msg);
ret = write(fd, buf, 200);
if (-1 == ret)
{
perror("write");
}
close(fd);
userInfo.result = 42;
for(i = 0; i < 20; i++)
{
if (uMge.flag[i] == 1)
{
if(strcmp(uMge.users[i].name,userInfo.name) != 0)
{
strcpy(userInfo.toName,uMge.users[i].name);
writeSize = write(uMge.users[i].socketfd, &userInfo, sizeof(userInfo));
}
}
}
userInfo.result = 41;
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 45:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
printf("用户%s被禁言 发送群消息失败\n", userInfo.name);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 51:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 61:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 70:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 73:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 74:
{
userInfo.result = 72;
printf("向用户%s发送result:%d\n",userInfo.toName,userInfo.result);
printf("用户%s向用户%s发送踢人指令\n", userInfo.name, userInfo.toName);
writeSize = write(userInfo.toSocketfd, &userInfo, sizeof(userInfo));
userInfo.result = 71;
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 80:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 83:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 84:
{
userInfo.result = 82;
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
printf("用户%s向用户%s发送禁言指令\n", userInfo.name, userInfo.toName);
writeSize = write(userInfo.toSocketfd, &userInfo, sizeof(userInfo));
userInfo.result = 81;
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 91:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
case 100:
{
printf("向用户%s发送result:%d\n",userInfo.name,userInfo.result);
writeSize = write(cfd, &userInfo, sizeof(userInfo));
break;
}
default:
{
printf("错误 收到result:%d", userInfo.result);
break;
}
}
memset(&userInfo, 0, sizeof(userInfo));
}
int temp;
temp = 0;
for (i = 0; i < 20; i++)
{
if(uMge.flag[i] == 1)
{
if(uMge.users[i].socketfd == cfd)
{
printf("检测到用户%s掉线了\n",uMge.users[i].name);
uMge.flag[i] = 0;
temp = 1;
break;
}
}
}
if(!temp)
{
printf("检测到用户退出客户端\n");
}
}
int main()
{
Initsystem();
int listen_sockfd;
int ret;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
pthread_mutex_init(&mutex, NULL);
listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sockfd == -1)
{
perror("create socket error");
return -1;
}
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERV_PORT);
ret = bind(listen_sockfd, (struct sockaddr *)&server_addr, sizeof (server_addr));
if (ret == -1)
{
perror ("bind error");
return -1;
}
ret = listen(listen_sockfd, 20);
if (ret == -1)
{
perror("listen error");
return -1;
}
while(1)
{
int clientfd;
socklen_t client_len = sizeof(client_addr);
clientfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &client_len);
if (clientfd == -1)
{
perror("accept error");
return -1;
}
pthread_t tid;
int ret = pthread_create(&tid, NULL, (void *)server_request, (void *)clientfd);
if (ret != 0)
{
printf ("create pthread error!\n");
return -1;
}
printf("检测到用户打开客户端\n");
pthread_detach(tid);
}
pthread_mutex_destroy(&mutex);
return 0;
}