头文件:
#ifndef _CHATROOM1_H_
#define _CHATROOM1_H_
//************库函数
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//************宏定义
#define PORT 8888
#define SUCCESS 10000000
#define FAILURE 10000001
#define RESIGER 1
#define LOGIN 2
#define OK 3 //发送成功
#define ERROR 4
#define FIND 5
#define SAME 6
#define SEND 7 //发送消息
#define UN 8 //不在线
#define MSG 9 //收到悄悄话
#define NUM 10 //查看在线人数
#define EXIT 11
#define GROUP 12
#define ERR 13 //群聊没人在线
#define ES 14 //表情
#define PS 15 //常用语
#define VIP 16
#define TALK 17 //解禁
#define SHUTUP 18 //禁言
#define OKK 19
#define OUTLINE 20
#define OKKK 21
#define SENDFILE 22
#define UNRE 23
#define REOK 24
//**************线程
pthread_t tid = 0;
//*************结构体
struct online // 在线链表
{
int sockfd;
char name[20];
struct online* next;
};
typedef struct online* LinkList;
struct senduser // 用户信息表
{
char id[20];
char name[20];
char toname[20];
char password[20];
char code[20]; //密保
char msg[200];
char onlinenum[30][30]; //在线的人
char filename[20];
char filemsg[200];
int e_s;
int p_s;
int vip; //1是vip 0则不是
int state; //1是被禁言 0则不是
int number; //人数
int cmd;
};
#endif
服务器:
#include "chatroom1.h"
int InitList(LinkList *l)
{
(*l) = (LinkList)malloc(sizeof(struct online));
(*l)->next = NULL;
}
int main()
{
//*******************初始化****************
sqlite3 *ppdb;
char sql[200] = {0};
int opt = 1, i = 0, j;
int sockfd, ret, fd[100] = {0};
struct senduser Recvbuf = {0};
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
fd_set Readfd, Tmpfd;
int maxfd;
sockfd = socket(PF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
{
perror("socket");
exit(1);
}
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("192.168.1.119");
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
printf("start server!\n");
//************初始化链表******************
LinkList online;
InitList(&online);
//******************创建开启数据库*****************************************
ret = sqlite3_open("user.db",&ppdb);
if(ret != SQLITE_OK)
{
perror("open");
exit(1);
}
printf("sqlite3 success!\n");
sprintf(sql, "create table if not exists user(id text primary key, password text, name text, code text, vip integer, state integer);");
ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
perror("exec1");
exit(1);
}
printf("create user db success!\n");
//******************绑定***************************************
ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(-1 == ret)
{
perror("bind");
exit(1);
}
ret = listen(sockfd, 8);
if(-1 == ret)
{
perror("listen");
exit(1);
}
FD_ZERO(&Readfd);
FD_ZERO(&Tmpfd);
FD_SET(sockfd, &Readfd);
maxfd = sockfd;
while(1)
{
Tmpfd = Readfd;
ret = select(maxfd + 1, &Tmpfd, NULL, NULL, NULL);
if(-1 == ret)
{
perror("select");
exit(1);
}
//****************************接受链接************************************
if(FD_ISSET(sockfd, &Tmpfd))
{
int length = sizeof(client_addr);
fd[i] = accept(sockfd, (struct sockaddr*)&client_addr, &length);
if(fd[i] < 0)
{
perror("accept");
exit(1);
}
printf("Accept %d, Port %d\n", fd[i], client_addr.sin_port);
FD_SET(fd[i], &Readfd);
maxfd = fd[i];
i++;
}
else
{
for(j = 0; j < i; j++)
{
if(FD_ISSET(fd[j], &Tmpfd))
{
ret = recv(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret < 0)
{
perror("recv");
return FAILURE;
}
//************************************注册************************
if(RESIGER == Recvbuf.cmd)
{
memset(sql, 0, sizeof(sql));
sprintf(sql, "insert into user(id, password, name, code, vip, state) values ('%s', '%s', '%s', '%s', '%d', '%d');", Recvbuf.id, Recvbuf.password, Recvbuf.name, Recvbuf.code, Recvbuf.vip, Recvbuf.state);
ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
perror("exec2");
Recvbuf.cmd = UNRE;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
}
else
{
Recvbuf.cmd = REOK;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
}
}
//************************************登录*********************************
if(Recvbuf.cmd == LOGIN)
{
char **Result = NULL;
int nrow;
memset(sql, 0, sizeof(sql));
sprintf(sql, "select id, password, name, vip, state from user where id = '%s' and password = '%s';", Recvbuf.id, Recvbuf.password);
ret = sqlite3_get_table(ppdb, sql, &Result, &nrow, NULL, NULL);
if(ret != SQLITE_OK)
{
perror("查询");
return FAILURE;
}
if(nrow == 1)
{
LinkList m = online->next;
while(m != NULL)
{
if(strcmp(m->name, Result[7]) == 0)
{
Recvbuf.cmd = SAME;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("samesend");
return FAILURE;
}
break;
}
m = m->next;
}
if(Recvbuf.cmd != SAME)
{
strcpy(Recvbuf.name, Result[7]);
Recvbuf.vip = *(Result[8]) - 48;
Recvbuf.state = *(Result[9]) - 48;
LinkList s = (LinkList)malloc(sizeof(struct online));
strcpy(s->name ,Recvbuf.name);
s->sockfd = fd[j];
s->next = online->next;
online->next = s;
Recvbuf.cmd = OK;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("Loginsend");
return FAILURE;
}
}
}
else
{
Recvbuf.cmd = ERROR;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("loginsend2");
return FAILURE;
}
}
}
//***********************************忘记密码*********************
if(Recvbuf.cmd == FIND)
{
char **Result = NULL;
int nrow;
memset(sql, 0, sizeof(sql));
sprintf(sql, "select id, code from user where id = '%s' and code = '%s';", Recvbuf.id, Recvbuf.code);
ret = sqlite3_get_table(ppdb, sql, &Result, &nrow, NULL, NULL);
if(ret != SQLITE_OK)
{
perror("查询2");
return FAILURE;
}
if(nrow == 1)
{
Recvbuf.cmd = OK;
memset(sql, 0, sizeof(sql));
sprintf(sql, "update user set password = '%s' where id = '%s';", Recvbuf.password, Recvbuf.id);
ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
perror("修改");
exit(1);
}
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("findsend1");
exit(1);
}
}
else
{
Recvbuf.cmd = ERROR;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("findsend");
return FAILURE;
}
}
}
//**********************************发送消息************************
if(Recvbuf.cmd == SEND)
{
LinkList m = online->next;
while(m != NULL)
{
if(strcmp(m->name, Recvbuf.toname) == 0)
{
break;
}
m = m->next;
}
if(m == NULL)
{
Recvbuf.cmd = UN;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendrecv");
return FAILURE;
}
}
else
{
Recvbuf.cmd = MSG;
ret = send(m->sockfd, &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendmsg");
return FAILURE;
}
Recvbuf.cmd = OK;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendrecv2");
return FAILURE;
}
}
}
//**********************************查看在线人数*******************
if(Recvbuf.cmd == NUM)
{
int i = 0;
Recvbuf.number = 0;
LinkList m = online->next;
while(m != NULL)
{
Recvbuf.number++;
strcpy(Recvbuf.onlinenum[i], m->name);
i++;
m = m->next;
}
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendnum");
return FAILURE;
}
}
//*********************************下线*********************
if(Recvbuf.cmd == EXIT)
{
LinkList tmp = online;
while(tmp->next != NULL)
{
if(strcmp(Recvbuf.name, tmp->next->name) == 0)
{
LinkList p = tmp->next;
tmp->next = p->next;
free(p);
break;
}
tmp = tmp->next;
}
}
//********************************群聊*********************
if(Recvbuf.cmd == GROUP)
{
int flag = 0;
LinkList q = online->next;
while(q != NULL)
{
if(q->sockfd != fd[j])
{
flag = 1;
ret = send(q->sockfd, &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendgroup");
return FAILURE;
}
}
q = q->next;
}
if(flag == 0)
{
Recvbuf.cmd = ERR;
send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
}
}
//********************************常用语*************
if(Recvbuf.cmd == PS)
{
LinkList m = online->next;
while(m != NULL)
{
if(strcmp(m->name, Recvbuf.toname) == 0)
{
break;
}
m = m->next;
}
if(m == NULL)
{
Recvbuf.cmd = UN;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendrecv");
return FAILURE;
}
}
else
{
ret = send(m->sockfd, &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendmsg");
return FAILURE;
}
Recvbuf.cmd = OK;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendrecv2");
return FAILURE;
}
}
}
//**********************表情*******************************
if(Recvbuf.cmd == ES)
{
LinkList m = online->next;
while(m != NULL)
{
if(strcmp(m->name, Recvbuf.toname) == 0)
{
break;
}
m = m->next;
}
if(m == NULL)
{
Recvbuf.cmd = UN;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendrecv");
return FAILURE;
}
}
else
{
ret = send(m->sockfd, &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendmsg");
return FAILURE;
}
Recvbuf.cmd = OK;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendrecv2");
return FAILURE;
}
}
}
//********************会员**********************
if(Recvbuf.cmd == VIP)
{
memset(sql, 0, sizeof(sql));
sprintf(sql, "update user set vip = '%d' where name = '%s';", Recvbuf.vip, Recvbuf.name);
ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
perror("vip");
return FAILURE;
}
}
//*****************解禁******************************
if(Recvbuf.cmd == TALK)
{
memset(sql, 0, sizeof(sql));
sprintf(sql, "update user set state = '%d' where name = '%s';", Recvbuf.state, Recvbuf.name);
ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
perror("talk");
return FAILURE;
}
}
//**************************禁言*************************
if(Recvbuf.cmd == SHUTUP)
{
LinkList m = online->next;
while(m != NULL)
{
if(strcmp(m->name, Recvbuf.toname) == 0)
{
break;
}
m = m->next;
}
if(m == NULL)
{
Recvbuf.cmd = UN;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendrecv");
return FAILURE;
}
}
else
{
memset(sql, 0, sizeof(sql));
sprintf(sql, "update user set state = 1 where name = '%s';", Recvbuf.toname);
ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
perror("shutup");
return FAILURE;
}
ret = send(m->sockfd, &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendshutup");
return FAILURE;
}
Recvbuf.cmd = OKK;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("OK1");
return FAILURE;
}
}
}
//***********************踢人*******************************
if(Recvbuf.cmd == OUTLINE)
{
LinkList m = online->next;
while(m != NULL)
{
if(strcmp(m->name, Recvbuf.toname) == 0)
{
break;
}
m = m->next;
}
if(m == NULL)
{
Recvbuf.cmd = UN;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendrecv");
return FAILURE;
}
}
else
{
ret = send(m->sockfd, &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendout");
return FAILURE;
}
LinkList tmp = online;
while(tmp->next != NULL)
{
if(strcmp(Recvbuf.toname, tmp->next->name) == 0)
{
LinkList p = tmp->next;
tmp->next = p->next;
free(p);
break;
}
tmp = tmp->next;
}
Recvbuf.cmd = OKKK;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("okkk");
return FAILURE;
}
}
}
//***********************文件传输************************
if(Recvbuf.cmd == SENDFILE)
{
LinkList m = online->next;
while(m != NULL)
{
if(strcmp(m->name, Recvbuf.toname) == 0)
{
break;
}
m = m->next;
}
if(m == NULL)
{
Recvbuf.cmd = UN;
ret = send(fd[j], &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendfile1");
return FAILURE;
}
}
else
{
ret = send(m->sockfd, &Recvbuf, sizeof(Recvbuf), 0);
if(ret == -1)
{
perror("sendfile2");
return FAILURE;
}
}
Recvbuf.cmd = 0;
}
//***************************************************************
}
}
}
}