另有管理员功能(禁言,解除禁言,踢人),文件传输功能,快捷短语和表情,拍一拍,VIP等功能
myhead.h
extern int flag;
extern struct online *head ;
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include<sqlite3.h>
#define SERVPORT 5001
#define SUCCESS 0
#define FAILURE -1
struct message
{
int action;//log
char id[20];
char name[20];
char password[20];
char toid[20];
char text[500];
char filename[20];
char fabulous[20];
char V[20];
int flag;
};
struct online
{
int c_fd;
char id[20];
char V[20];
int flag;
struct online * next;
};
int insert_sql(struct message *msg);
int insert_view(struct message *msg);
int setup_sql();
int inquire_nocb(int connfd,struct message * MSG);
int find_id(struct message *msg);
int find_np(struct message *msg);
void insert_online(struct online *user);
int check_ifonline(struct message *msg,struct online *head);
void reg(int connfd,struct message * MSG);
void logged(int connfd,struct message * MSG);
int f_id(char * toid,struct message * MSG,int connfd);
void privatechat(int connfd,struct message * MSG);
void groupchat(int connfd,struct message * MSG);
void online(int connfd,struct message * MSG);
void release_link();
int delete(int connfd,struct message * msg);
void offline(int connfd,struct message * MSG);
void off(int connfd,struct message * MSG);
void adm(int connfd,struct message * MSG);
void ban(int connfd,struct message * MSG);
void unban(int connfd,struct message * MSG);
void expel(int connfd,struct message * MSG);
void vchat(int connfd,struct message * MSG);
void clean(int connfd,struct message * MSG);
void wfile(int connfd,struct message * MSG);
void * thread_func(void * arg);
void * thread_udp(void * arg);
serve.c
#include "../../include/myhead.h"
extern int flag;
extern struct online *head ;
int insert_sql(struct message *msg)
{
sqlite3 * database;
int ret = sqlite3_open("usr.db", &database);
if (ret != SQLITE_OK)
{
printf ("打开数据库失败\n");
return FAILURE;
}
char *errmsg = NULL;
char buf[100];
sprintf(buf, "insert into usr values('%s','%s','%s');",msg->id, msg->name, msg->password);
ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("添加用户失败:%s\n", errmsg);
return FAILURE;
}
sqlite3_close(database);
return SUCCESS;
}
int insert_view(struct message *msg)
{
sqlite3 * database;
int ret = sqlite3_open("usr.db", &database);
if (ret != SQLITE_OK)
{
printf ("打开数据库失败\n");
return FAILURE;
}
char *errmsg = NULL;
char buf[1024];
sprintf(buf, "insert into viewchat values('%s','%s','%s');",msg->id, msg->toid, msg->text);
ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("添加用户失败:%s\n", errmsg);
return FAILURE;
}
sqlite3_close(database);
return SUCCESS;
}
int setup_sql()
{
sqlite3 * database;
int ret = sqlite3_open("usr.db", &database);
if (ret != SQLITE_OK)
{
printf ("打开数据库失败\n");
return FAILURE;
}
char *errmsg = NULL;
char *sql = "create table if not exists usr(id text primary key,name text,password text);";
ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("用户表创建失败:%s\n", errmsg);
return FAILURE;
}
char *ql = "create table if not exists viewchat(id text,toid text,chat text);";
ret = sqlite3_exec(database, ql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("用户表创建失败:%s\n", errmsg);
return FAILURE;
}
sqlite3_close(database);
return SUCCESS;
}
int inquire_nocb(int connfd,struct message * MSG)
{
sqlite3 * database;
char *sql = NULL;
char ** azresult = NULL;
char * errmsg = NULL;
int n_row,n_col;
int i;
int ret = sqlite3_open("usr.db", &database);
if (ret != SQLITE_OK)
{
printf ("打开数据库失败\n");
return FAILURE;
}
sql = "select * from viewchat;";
ret = sqlite3_get_table(database,sql,&azresult,&n_row,&n_col,&errmsg);
if(SQLITE_OK != ret)
{
printf("get tabble error! %s\n",errmsg);
return FAILURE;
}
// printf("n_row = %d n_col = %d\n",n_row,n_col);
//printf("the result of inquire is:\n");
for(i = n_col; i < (n_row + 1) * n_col ;i++)
{
//printf("%10s",azresult[i]);
// memset(MSG,0,sizeof(struct message));
MSG->action = 12;
if(i % 3 == 0)
{
strcpy(MSG->id,azresult[i]);
// printf("%s",MSG->id);
}
if(i % 3 == 1)
{
strcpy(MSG->toid,azresult[i]);
// printf("%s",MSG->toid);
}
if(i % 3 == 2)
{
strcpy(MSG->text,azresult[i]);
// printf("%s",MSG->text);
write(connfd,MSG,sizeof(struct message));
}
sleep(0.1);
/*if((i + 1) % n_col == 0)
{
printf("\n");
}*/
}
return SUCCESS;
sqlite3_close(database);
}
void del_fromsql(struct message *msg)
{
sqlite3 * database;
int ret = sqlite3_open("usr.db", &database);
if (ret != SQLITE_OK)
{
printf ("打开数据库失败\n");
return;
}
char *errmsg = NULL;
char buf[100];
sprintf(buf, "delete from usr where id = '%s'", msg->id);
ret = sqlite3_exec(database, buf, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("删除用户失败:%s\n", errmsg);
return;
}
sqlite3_close(database);
return;
}
int find_id(struct message *msg)
{
sqlite3 * database;
int ret = sqlite3_open("usr.db", &database);
if (ret != SQLITE_OK)
{
printf ("打开数据库失败\n");
return FAILURE;
}
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char *sql = "select id from usr;";
ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("用户查找失败:%s\n", errmsg);
return FAILURE;
}
int i;
for(i=0; i<(nrow+1) * ncolumn; i++)
{
if(strcmp(resultp[i], msg->id) == 0)
return SUCCESS;
}
return FAILURE;
}
int find_np(struct message *msg)
{
sqlite3 * database;
int ret = sqlite3_open("usr.db", &database);
if (ret != SQLITE_OK)
{
printf ("打开数据库失败\n");
return FAILURE;
}
char *errmsg = NULL;
char **resultp = NULL;
int nrow, ncolumn;
char *sql = "select * from usr";
ret = sqlite3_get_table(database, sql, &resultp, &nrow, &ncolumn, &errmsg);
if (ret != SQLITE_OK)
{
printf ("用户查找失败:%s\n", errmsg);
return FAILURE;
}
int i;
for(i = 0; i < (nrow+1) * ncolumn; i++)
{
if(strcmp(resultp[i], msg->id) == 0 &&
strcmp(resultp[i+1], msg->password) == 0)
return SUCCESS;
}
return FAILURE;
}
void insert_online(struct online *user)
{
user->next = head;
head = user;
}
int check_ifonline(struct message *msg,struct online *head)
{
struct online *p = head;
while(p != NULL)
{
if(strcmp(msg->id,p->id) == 0)
{
return SUCCESS;
}
else
{
p = p->next;
}
}
return FAILURE;
}
void reg(int connfd,struct message * MSG)
{
printf("正在查找该用户是否被注册...\n");
if(find_id(MSG) == SUCCESS)
{
// printf("用户%s已经被注册\n",MSG->id);
MSG->action = -1;
}
else if(FAILURE == insert_sql(MSG))
{
printf("数据库添加失败\n");
MSG->action = -1;
}
else
{
MSG->action = 1;
printf("数据库添加成功\n");
}
// printf("4");
write(connfd,MSG,sizeof(struct message));
// printf("3");
}
void logged(int connfd,struct message * MSG)
{
printf("正在查找该用户有没有注册...\n");
if(find_id(MSG) == SUCCESS)
{
if(find_np(MSG) == SUCCESS)
{
if(check_ifonline(MSG,head) == SUCCESS)
{
MSG->action = -2;
//printf("用户%s已经登陆过了\n",MSG->id);
}
else
{
// printf("该用户是普通用户\n");
struct online *user;
user = (struct online *)malloc(sizeof(struct online));
user->c_fd = connfd;
strcpy(user->V,"0");
user->flag = 0;
strcpy(user->id,MSG->id);
insert_online(user);
MSG->action = 2;
//printf("用户%s登陆成功\n",MSG->id);
}
}
else
{
MSG->action = 4;
//printf("用户%s密码输入错误\n",MSG->id);
}
}
else
{
MSG->action = -4;
//printf("用户%s还没有注册\n",MSG->id);
}
write(connfd,MSG,sizeof(struct message));
}
int f_id(char * toid,struct message * MSG,int connfd)
{
if(head == NULL)
{
// printf("++");
return FAILURE;
}
//printf("\n-%s-\n",toid);
struct online *temp = head;
while(temp != NULL)
{
//printf("-%s-",toid);
//printf("+%s+",temp->id);
if(strcmp(toid,temp->id) == 0)
{
// printf("\nqq%dqq\n",temp->c_fd);
MSG->action = 3;
//MSG->flag = temp->flag;
insert_view(MSG);
//printf("%s\n",MSG->text);
write(temp->c_fd,MSG,sizeof(struct message));
write(connfd,MSG,sizeof(struct message));
return temp->c_fd;
}
else
{
temp = temp->next;
}
}
// printf("//");
return FAILURE;
}
void privatechat(int connfd,struct message * MSG)
{
int c_fd;
//printf("%s",MSG->toid);
//printf("***%d***",MSG->flag);
//printf("%s",MSG->id);
struct online *temp = head;
while(temp != NULL)
{
//printf("-%s-",toid);
//printf("+%s+",temp->id);
if(strcmp(MSG->id,temp->id) == 0)
{
// printf("\nqq%dqq\n",temp->c_fd);
MSG->action = 3;
MSG->flag = temp->flag;
if(MSG->flag == 1)
{
write(connfd,MSG,sizeof(struct message));
break;
}
else
{
if((c_fd = f_id(MSG->toid,MSG,connfd)) == FAILURE)
{
MSG->action = -3;
write(connfd,MSG,sizeof(struct message));
}
break;
}
}
else
{
temp = temp->next;
}
}
/* if((c_fd = f_id(MSG->toid,MSG,connfd)) == FAILURE)
{
MSG->action = -3;
write(connfd,MSG,sizeof(struct message));
}*/
/*else
{
printf("\n%d\n",c_fd);
MSG->action = 3;
printf("%s\n",MSG->text);
write(c_fd,MSG,sizeof(struct message));
}*/
}
void groupchat(int connfd,struct message * MSG)
{
struct online *p =head;
int c_fd;
while(p != NULL)
{
insert_view(MSG);
MSG->action = 5;
c_fd = p->c_fd;
MSG->flag = flag;
write(c_fd,MSG,sizeof(struct message));
p = p->next;
}
}
void online(int connfd,struct message * MSG)
{
struct online *p = head;
int c_fd = connfd;
memset(MSG->text,0,sizeof(MSG->text));
while(p != NULL)
{
MSG->action = 6;
//c_fd = p->c_fd;
//printf("%s is online",p->id);
//memset(&MSG->text,0,sizeof(MSG->text));
strcat(MSG->text,p->id);
strcat(MSG->text," ");
p = p->next;
}
write(c_fd,MSG,sizeof(struct message));
//printf("%s",MSG->text);
}
void release_link()
{
struct online *tmp = NULL;
tmp = head;
while(head != NULL)
{
tmp = head;
head = (head) -> next;
free(tmp);
}
if( head == NULL)
{
printf("link is emtpy\n");
return;
}
}
int delete(int connfd,struct message * msg)
{
struct online *q = NULL;
struct online *p = NULL;
p = head;
int c_fd;
if(NULL == head)
{
printf("link is empty !\n");
return FAILURE;
}
if(head != NULL)
{
while(p != NULL)
{
if(strcmp(msg->id,p->id) == 0)
{
if(p == head)
{
c_fd = p->c_fd;
head = p->next;
free(p);
return c_fd;
break;
}
else
{
c_fd = p->c_fd;
q->next = p->next;
free(p);
return c_fd;
break;
}
}
else
{
q = p;
p = p->next;
}
}
}
else
{
printf("no such node!\n");
}
return FAILURE;
}
void offline(int connfd,struct message * MSG)
{
int c_fd;
c_fd = delete(connfd,MSG);
MSG->action = 7;
write(c_fd,MSG,sizeof(struct message));
}
void off(int connfd,struct message * MSG)
{
//release_link();
del_fromsql(MSG);
MSG->action = -6;
write(connfd,MSG,sizeof(struct message));
}
void adm(int connfd,struct message * MSG)
{
//struct master m;
//printf("1.%s",m.id);
//printf("2.%s",MSG->id);
if(strcmp(MSG->id,"root") == 0)
{
if(strcmp(MSG->password,"123") == 0)
{
MSG->action = 8;
write(connfd,MSG,sizeof(struct message));
}
else
{
MSG->action = -8;
write(connfd,MSG,sizeof(struct message));
}
}
else
{
MSG->action = -8;
write(connfd,MSG,sizeof(struct message));
}
}
void ban(int connfd,struct message * MSG)
{
struct online *temp = head;
//printf("1");
if(head == NULL)
{
return ;
}
while(temp != NULL)
{
//printf("2");
if(strcmp(MSG->id,temp->id) == 0)
{
//printf("3");
if(strcmp(temp->V,"1") == 0)
{
MSG->action = -9;
//printf("4");
write(connfd,MSG,sizeof(struct message));
break;
}
else
{
//printf("5");
// temp->flag =1;
temp->flag = 1;
MSG->flag = 1;
MSG->action = 3;
printf("/%d/",MSG->flag);
write(temp->c_fd,MSG,sizeof(struct message));
break;
}
}
else
{
temp = temp->next;
}
}
}
void unban(int connfd,struct message * MSG)
{
struct online *temp = head;
if(head == NULL)
{
return ;
}
while(temp != NULL)
{
if(strcmp(MSG->id,temp->id) == 0)
{
temp->flag = 0;
MSG->flag = -1;
write(temp->c_fd,MSG,sizeof(struct message));
MSG->action = 9;
write(connfd,MSG,sizeof(struct message));
break;
}
else
{
temp = temp->next;
}
}
}
void expel(int connfd,struct message * MSG)
{
struct online *temp =head;
while(temp != NULL)
{
//printf("-%s-",toid);
//printf("+%s+",temp->id);
if(strcmp(MSG->id,temp->id) == 0)
{
if(strcmp(temp->V,"1") == 0)
{
MSG->action = -11;
write(connfd,MSG,sizeof(struct message));
break;
}
else
{
MSG->action = 11;
write(connfd,MSG,sizeof(struct message));
offline(connfd,MSG);
break;
}
}
else
{
temp = temp->next;
}
}
}
void vchat(int connfd,struct message * MSG)
{
inquire_nocb(connfd,MSG);
}
void clean(int connfd,struct message * MSG)
{
sqlite3 * database;
char *sql = NULL;
char * errmsg = NULL;
int ret = sqlite3_open("usr.db", &database);
if (ret != SQLITE_OK)
{
printf ("打开数据库失败\n");
return ;
}
sql = "delete from viewchat;";
ret = sqlite3_exec(database, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf ("清除失败:%s\n", errmsg);
return ;
}
sqlite3_close(database);
MSG->action = 13;
write(connfd,MSG,sizeof(struct message));
}
void wfile(int connfd,struct message * MSG)
{
printf("%s",MSG->name);
MSG->action = 14;
FILE* file = fopen(MSG->name,"r");
//FILE* file = fopen("2.c","r");
if(file == NULL)
{
//printf("error");
perror("create");
}
while(!feof(file))
{
printf("send");
fread(MSG->text,1,sizeof(MSG->text),file);
write(connfd,MSG,sizeof(struct message));
}
fclose(file);
}
void recv_file(int connfd,struct message * MSG)
{
FILE* fp = NULL;
printf("%s",MSG->filename);
fp = fopen(MSG->filename,"w");
//fp = fopen("s.c","w");
if(fp == NULL)
{
printf("creatr fp failure\n");
perror("create");
exit(0);
}
printf("recv begin\n");
fprintf(fp,"%s",MSG->text);
fclose(fp);
strcpy(MSG->text,MSG->filename);
groupchat(connfd,MSG);
}
void fab(int connfd,struct message * msg)
{
printf("1");
struct online *temp = head;
while(temp != NULL)
{
//printf("-%s-",toid);
//printf("+%s+",temp->id);
if(strcmp(msg->toid ,temp->id) == 0)
{
// printf("\nqq%dqq\n",temp->c_fd);
msg->action = 3;
//msg->flag = temp->flag;
printf("*%d*",msg->action);
strcpy(msg->fabulous,"1");
strcpy(msg->text,"hello");
printf("%s",msg->fabulous);
//printf("%s\n",MSG->text);
write(temp->c_fd,msg,sizeof(struct message));
break;
}
else
{
temp = temp->next;
}
}
sleep(3);
msg->action =17;
write(connfd,msg,sizeof(msg));
}
void VIP(int connfd,struct message * msg)
{
msg->action = 19;
struct online *temp = head;
while(temp != NULL)
{
if(strcmp(msg->id,temp->id) == 0)
{
//temp->V = msg->V;
strcpy(temp->V,"1");
strcpy(msg->V,"1");
printf("*%s*",msg->V);
write(connfd,msg,sizeof(struct message));
break;
}
else
{
temp = temp->next;
}
}
}
void * thread_func(void * arg)
{
int connfd, n;
struct message MSG;
connfd = *((int*)arg);
while(1)
{
//printf("*%d*",connfd);
//n = read(connfd, &MSG,sizeof(MSG));
//n = recvfrom(connfd, &MSG, 1000, 0, (struct sockaddr *)&cliaddr, &clilen);
memset(&MSG,0,sizeof(MSG));
n = read(connfd,&MSG,sizeof(MSG));
if (0 == n)
{
printf("客户端离线!\n");
pthread_exit(NULL);
// printf("1");
}
// printf("received the following:\n");
//printf("*%d*\n",MSG.action);
//printf("2");
// printf("*-%s-*\n",MSG.filename);
//printf("%s\n",MSG.name);
switch(MSG.action)
{
case 1:
{
reg(connfd,&MSG);
break;
}
case 2:
{
logged(connfd,&MSG);
break;
}
case 3:
{
privatechat(connfd,&MSG);
break;
}
case 5:
{
groupchat(connfd,&MSG);
break;
}
case 6:
{
online(connfd,&MSG);
break;
}
case -6:
{
off(connfd,&MSG);
break;
}
case 7:
{
offline(connfd,&MSG);
break;
}
case 8:
{
adm(connfd,&MSG);
break;
}
case 9:
{
ban(connfd,&MSG);
break;
}
case 10:
{
unban(connfd,&MSG);
break;
}
case 11:
{
expel(connfd,&MSG);
break;
}
case 12:
{
vchat(connfd,&MSG);
break;
}
case 13:
{
clean(connfd,&MSG);
break;
}
case 14:
{
wfile(connfd,&MSG);
break;
}
case 15:
{
recv_file(connfd,&MSG);
break;
}
case 16:
{
MSG.action = 16;
write(connfd,&MSG,sizeof(MSG));
break;
}
case 17:
{
fab(connfd,&MSG);
break;
}
case 18:
{
MSG.action = 18;
write(connfd,&MSG,sizeof(MSG));
break;
}
case 19:
{
VIP(connfd,&MSG);
break;
}
}
}
close(connfd);
}
/*void * thread_udp(void * arg)
{
struct message MSG;
int ls, connfd, n;
struct sockaddr_in ser, cli;
socklen_t clilen;
char buf[1000];
struct online *temp = head;
connfd = *((int*)arg);
printf("-%d-",connfd);
while (1)
{
clilen = sizeof(cli);
n = recvfrom(connfd , buf, 1000, 0, (struct sockaddr *)&cli, &clilen);
sendto(connfd , buf, n, 0, (struct sockaddr *)&cli, sizeof(cli));
buf[n] = '\0';
printf("%s\n", buf);
while(temp != NULL)
{
//printf("-%s-",toid);
//printf("+%s+",temp->id);
if(strcmp(MSG.toid ,temp->id) == 0)
{
// printf("\nqq%dqq\n",temp->c_fd);
MSG.action = 3;
MSG.flag = temp->flag;
strcpy(MSG.text,buf);
// insert_view(MSG);
//printf("%s\n",MSG->text);
write(temp->c_fd,&MSG,sizeof(struct message));
// write(connfd,MSG,sizeof(struct message));
break;
}
else
{
temp = temp->next;
}
}
}
}
*/
main.c
#include "../../include/myhead.h"
int flag = 0;
struct online *head = NULL;
int main()
{
int ret;
// printf("1");
int i = 0;
// struct master M;
pthread_t a_thread;
// pthread_t tid;
//void * thread_result;
int listenfd, connfd;
struct sockaddr_in servaddr, cliaddr;
socklen_t clilen;
//printf("2");
setup_sql();
/*strcpy(M.id,"root");
strcpy(M.password,"123");*/
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1)
{
perror ("socket");
return -1;
}
//printf("3");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVPORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
ret = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if (ret == -1)
{
perror ("bind");
return -1;
}
//printf("4");
ret = listen(listenfd, 10);
if (ret == -1)
{
perror ("listen");
return -1;
}
/*
int ls,n;
struct sockaddr_in ser, cli;
char msg[1000];
ls = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&ser, sizeof(ser));
ser.sin_family = AF_INET;
ser.sin_port = htons(SERVPORT);
ser.sin_addr.s_addr = htonl(INADDR_ANY);
bind(ls, (struct sockaddr *)&ser, sizeof(ser));
printf ("等待客户端连接.......\n");
if( pthread_create(&tid,NULL,thread_udp,(void *)&ls) != 0)
{
printf("create fail error !\n");
exit(-1);
}
*/
printf ("等待客户端连接.......\n");
while (1)
{
clilen = sizeof(cliaddr);
for(;i < 10;i++)
{
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
if (connfd == -1)
{
perror ("accept");
return -1;
}
printf ("成功接收一个客户端: %s\n", inet_ntoa(cliaddr.sin_addr));
if( pthread_create(&a_thread,NULL,thread_func,(void *)&connfd) != 0)
{
printf("create fail error !\n");
exit(-1);
}
}
if(i == 10)
{
printf("客户端已满!\n");
break;
}
}
pthread_detach(a_thread);
close(listenfd);
return 0;
}