#include
#include
#include
#include
#include
#include
#include
#include
#include “chat.h”
#include
#include
#define PORT 9997
void more_chat(int cmd,long client_socket)//群聊
{
struct chat_name
{
int data;
char name1[20];
char buf[1024];
}more;
struct send_msg
{
int data1;
int result;
char name2[20];
char buf1[1024];
}send;
sqlite3 * db;
char **resultp;
int ret = sqlite3_open("chat.db", &db);
if(ret != SQLITE_OK)
{
printf("打开数据库失败\n");
return;
}
while(1)
{
ret = read(client_socket, &more,sizeof(struct chat_name));
if (strcmp(more.buf,"end") == 0)
{
printf ("群聊退出\n");
return;
}
char str[1000];
char *errmsg;
sprintf(str, "select Power from user_online where name = '%s'",more.name1);
int nrow;
int ncolumn;
ret = sqlite3_get_table(db,str,&resultp,&nrow,&ncolumn,&errmsg );
if (SQLITE_OK != ret)
{
printf("exec失败:%s\n",errmsg);
sqlite3_free(errmsg);
return;
}
if(atoi(resultp[1]) == 0)
{
printf("你被禁言了\n");
send.data1 = more.data;
send.result = quit;
write(client_socket,&send,sizeof(struct send_msg));
}
else
{
send.data1 = more.data;
strcpy(send.name2,more.name1);
strcpy(send.buf1,more.buf);
send.result = speak;
printf ("%s请求向所有人发送一条信息\n",more.name1);
const char *sql = "create table if not exists msg_record(send_Name TEXT,get_name TEXT,Msg TEXT)";
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
memset (str,0,sizeof(str));
sprintf(str, "insert into msg_record values('%s','%s','%s')",more.name1,"所有人",more.buf);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
memset (str,0,sizeof(str));
sprintf(str, "select Socket from user_online where name <> '%s'",more.name1);
ret = sqlite3_get_table(db,str,&resultp,&nrow,&ncolumn,&errmsg );
if (SQLITE_OK != ret)
{
printf("exec失败:%s\n",errmsg);
sqlite3_free(errmsg);
return;
}
int i;
for(i = ncolumn;i < (nrow+1)*ncolumn;i++)
{
printf ("套接字:%s\n",resultp[i]);
write(atoi(resultp[i]),&send,sizeof(struct send_msg));
}
}
}
sqlite3_free_table(resultp);
sqlite3_close(db);
}
void one_chat(int cmd,long client_socket)//私聊
{
struct chat_name
{
int data;
char name[20];
char name1[20];
char buf[1024];
}one;
struct send_msg
{
int data1;
int result;
char name2[20];
char buf1[1024];
}send;
sqlite3 * db;
char **resultp;
int ret = sqlite3_open("chat.db", &db);
if(ret != SQLITE_OK)
{
printf("打开数据库失败\n");
return;
}
while(1)
{
read(client_socket, &one,sizeof(struct chat_name));
printf ("%s请求向%s发送消息\n",one.name1,one.name);
if (strcmp(one.buf,"end") == 0)
{
printf ("私聊退出\n");
return;
}
char *errmsg;
char str[1000];
sprintf(str,"select Power from user_online where name = '%s'",one.name1);
int nrow;
int ncolumn;
ret = sqlite3_get_table(db,str,&resultp,&nrow,&ncolumn,&errmsg );
if (SQLITE_OK != ret)
{
printf("exec失败:%s\n",errmsg);
sqlite3_free(errmsg);
return;
}
if (atoi(resultp[1]) == 0)
{
printf ("%s被禁言了\n",one.name1);
send.data1 = one.data;
send.result = quit;
write(client_socket,&send,sizeof(struct send_msg));
}
else
{
memset(str, 0, sizeof(str));
sprintf(str,"select Socket from user_online where name = '%s'",one.name);
ret = sqlite3_get_table(db,str,&resultp,&nrow,&ncolumn,&errmsg );
if (SQLITE_OK != ret)
{
printf("exec失败:%s\n",errmsg);
sqlite3_free(errmsg);
return;
}
if (nrow == 0)
{
printf ("聊天对象不在线\n");
}
else
{
printf ("%s的套接字是%s\n",one.name,resultp[1]);
send.data1 = one.data;
strcpy(send.name2,one.name1);
strcpy(send.buf1,one.buf);
send.result = speak;
write(atoi(resultp[1]),&send,sizeof(struct send_msg));
const char *sql = "create table if not exists msg_record(send_Name TEXT,get_name TEXT,Msg TEXT)";
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
memset(str, 0, sizeof(str));
sprintf(str, "insert into msg_record values('%s','%s','%s')",one.name,one.name1,one.buf);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
}
}
}
sqlite3_free_table(resultp);
sqlite3_close(db);
}
void change_passwd(int cmd,long client_socket)//修改密码
{
msg data;
rep data1;
int ret = read(client_socket, &data,sizeof(msg));
printf("%s请求更改密码,新密码是%s\n",data.name,data.passwd);
sqlite3 * db;
ret = sqlite3_open("chat.db", &db);
if(ret != SQLITE_OK)
{
printf("打开数据库失败\n");
return;
}
char *errmsg;
char str[1000];
sprintf(str, "update reg_show set Passwd = '%s' where Name = '%s'",data.passwd,data.name);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
data1.result = 2001;
data1.cmd = cmd;
write(client_socket,&data1,sizeof(rep));
sqlite3_close(db);
}
void delete_user(int cmd,long client_socket)//注销用户
{
rep data1;
char name[20] = {0};
int ret = read(client_socket,name,sizeof(name));
printf("%s用户请求注销\n",name);
sqlite3 * db;
ret = sqlite3_open("chat.db", &db);
if(ret != SQLITE_OK)
{
printf("打开数据库失败\n");
return;
}
char *errmsg;
char str[1000];
sprintf(str, "delete from reg_show where Name = '%s'",name);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
sprintf(str, "delete from user_online where Name = '%s'",name);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
data1.result = 3001;
data1.cmd = cmd;
write(client_socket,&data1,sizeof(rep));
sqlite3_close(db);
}
void quit_chat(int cmd,long client_socket)//退出聊天,返回登录界面
{
char name[20] = {0};
int ret = read(client_socket,name,sizeof(name));
printf("---------\n");
printf("%s, len = %ld\n",name, strlen(name));
sqlite3 * db;
ret = sqlite3_open(“chat.db”, &db);
if(ret != SQLITE_OK)
{
printf(“打开数据库失败\n”);
return;
}
char *errmsg;
char str[1000];
sprintf(str, "delete from user_online where Name = '%s'",name);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
write(client_socket,&cmd,sizeof(int));
sqlite3_close(db);
}
void give_file(int cmd,long client_socket)//发送文件
{
struct _file
{
char file_name[20];
char rev_name[20];
char send_name[20];
off_t len;
}file;
struct send_msg
{
int data1;
int result;
char name2[20];
char buf1[1024];
char name1[20];
}send;
read(client_socket, &file, sizeof(file));
send.data1 = cmd;
memset(send.name1, 0, sizeof(send.name1));
strcpy(send.name1, file.send_name);
printf("sendname = %s\n", send.name1);
memset(send.name2, 0, sizeof(send.name2));
strcpy(send.name2, file.file_name);
printf("filename = %s\n", send.name2);
send.result = 0;
printf ("%s,%s,%s\n",file.file_name,file.rev_name,file.send_name);
sqlite3 * db;
int ret = sqlite3_open("chat.db", &db);
if(ret != SQLITE_OK)
{
printf("打开数据库失败\n");
return;
}
char str[100];
sprintf(str, "select Socket from user_online where Name = '%s'", file.rev_name);
char **resultp;
int nrow;
int ncolumn;
char *errmsg;
ret = sqlite3_get_table(db,str,&resultp,&nrow,&ncolumn,&errmsg );
if (SQLITE_OK != ret)
{
printf("exec失败:%s\n",errmsg);
sqlite3_free(errmsg);
return;
}
if (nrow == 0)
{
printf("查无此人\n");
send.result = 4001;
}
else
{
printf("%s\n",resultp[1]);
send.data1 = cmd;
send.result = 4002;
}
int recv_socket = atoi(resultp[1]);
printf("recv_socket = %d\n", recv_socket);
write(recv_socket, &send, sizeof(send));
write(recv_socket, &file.len, sizeof(file.len));
char buf[1024] = {0};
int single_len = sizeof(buf);
while(1)
{
if(file.len < sizeof(buf))
single_len = file.len;
if(file.len <= 0)
break;
memset(buf, 0, sizeof(buf));
read(client_socket, buf, single_len);
memset(send.buf1, 0, sizeof(send.buf1));
strcpy(send.buf1, buf);
write(recv_socket, buf, single_len);
file.len -= single_len;
}
sqlite3_free_table(resultp);
sqlite3_close(db);
}
void quiet_user(int cmd,long client_socket)//禁言
{
rep data;
int i = 0;
char name[20];
memset(name,0,sizeof(name));
read(client_socket,name,sizeof(name));
printf (“超级用户请求将%s禁言\n”,name);
sqlite3 * db;
int ret = sqlite3_open(“chat.db”, &db);
if(ret != SQLITE_OK)
{
printf(“打开数据库失败\n”);
return;
}
char *errmsg;
char str[1000];
sprintf(str, "update user_online set Power = %d where Name = '%s'",i,name);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
data.cmd = cmd;
data.result = 4001;
write(client_socket,&data,sizeof(rep));
sqlite3_close(db);
}
void speak_user(int cmd,long client_socket)//解禁
{
rep data;
char name[20];
memset(name,0,sizeof(name));
read(client_socket,name,sizeof(name));
printf (“超级用户请求将%s禁言\n”,name);
sqlite3 * db;
int ret = sqlite3_open(“chat.db”, &db);
if(ret != SQLITE_OK)
{
printf(“打开数据库失败\n”);
return;
}
char *errmsg;
char str[1000];
sprintf(str, "update user_online set Power = %d where Name = '%s'",1,name);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
data.cmd = cmd;
data.result = 7001;
write(client_socket,&data,sizeof(rep));
sqlite3_close(db);
}
void function_meau(long client_socket)//功能菜单
{
while (1)
{
int cmd;
int ret = read(client_socket, &cmd,sizeof(int));
printf(“cmd = %d\n”,cmd);
if (-1 == ret)
{
perror(“read失败”);
return ;
}
if (0 == ret)
{
break;
}
switch(cmd)
{
case 2:
one_chat(cmd,client_socket);
break;
case 3:
more_chat(cmd,client_socket);
break;
case 5:
change_passwd(cmd,client_socket);
break;
case 6:
delete_user(cmd,client_socket);
return;
case 8:
give_file(cmd,client_socket);
break;
case 9:
quit_chat(cmd,client_socket);
return;
case 10:
quiet_user(cmd,client_socket);
break;
case 11:
speak_user(cmd,client_socket);
break;
default:
break;
}
}
}
//注册
void reg(int cmd, int client_socket)
{
msg data_msg;
rep data_rep;
int ret = read(client_socket, &data_msg,sizeof(msg));
printf ("用户名:%s,密码:%s请求注册\n",data_msg.name,data_msg.passwd);
sqlite3 * db;
ret = sqlite3_open("chat.db", &db);
if(ret != SQLITE_OK)
{
printf("打开数据库失败\n");
return;
}
char sql[100];
sprintf(sql, "select * from reg_show where Name = '%s'", data_msg.name);
char **resultp;
int nrow;
int ncolumn;
char *errmsg;
ret = sqlite3_get_table(db,sql,&resultp,&nrow,&ncolumn,&errmsg );
if (SQLITE_OK != ret)
{
printf("exec失败:%s\n",errmsg);
sqlite3_free(errmsg);
return;
}
if(nrow == 0)
{
printf("注册成功\n");
data_rep.result =REG_OK;
}
else
{
printf("注册失败,该用户名已被注册\n");
data_rep.result = REG_USEREXIST;
}
if (data_rep.result == REG_OK)
{
char str[1000];
sprintf(str, "insert into reg_show values('%s','%s')",data_msg.name,data_msg.passwd);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
}
data_rep.cmd = cmd;
// 注册过程
write(client_socket, &data_rep, sizeof(rep));
sqlite3_free_table(resultp);
sqlite3_close(db);
}
//登录
void mylog(int cmd, long client_socket)
{
msg data_msg;
rep data_rep;
int ret = read(client_socket, &data_msg,sizeof(msg));
printf (“用户名:%s,密码:%s请求登录\n”,data_msg.name,data_msg.passwd);
if (ret == -1)
{
perror(“读失败”);
return;
}
sqlite3 * db;
ret = sqlite3_open("chat.db", &db);
if(ret != SQLITE_OK)
{
printf("打开数据库失败\n");
return;
}
char *errmsg;
const char *sql = "create table if not exists user_online(Name TEXT,Socket INTEGER,Power INTEGER)";
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
char str[100];
sprintf(str, "select passwd from reg_show where Name = '%s'", data_msg.name);
char **resultp;
int nrow;
int ncolumn;
ret = sqlite3_get_table(db,str,&resultp,&nrow,&ncolumn,&errmsg );
if (SQLITE_OK != ret)
{
printf("exec失败:%s\n",errmsg);
sqlite3_free(errmsg);
return;
}
if(nrow == 0)
{
printf("该用户尚未注册\n");
data_rep.result = LOG_USEREXIST;
}
else if(strcmp(resultp[1], data_msg.passwd) == 0)
{
printf("密码正确,登录成功\n");
sprintf(str, "insert into user_online values('%s',%ld,%d)",data_msg.name,client_socket,1);
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
data_rep.result = LOG_OK;
}
data_rep.cmd = cmd;
write(client_socket,&data_rep,sizeof(rep));
if (data_rep.result == LOG_OK)
{
printf("进入聊天界面\n");
function_meau(client_socket);
}
sqlite3_free_table(resultp);
sqlite3_close(db);
}
void *handl_client(void *v)//子线程处理函数
{
long client_socket = (long)v;
sqlite3 * db;
int ret = sqlite3_open("chat.db", &db);
if(ret != SQLITE_OK)
{
printf("打开数据库失败\n");
return;
}
char *errmsg;
const char *sql = "create table if not exists reg_show(Name TEXT,Passwd TEXT)";
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
char str[100];
sprintf(str, "select * from reg_show where Name = '%s'","root");
char **resultp;
int nrow;
int ncolumn;
ret = sqlite3_get_table(db,str,&resultp,&nrow,&ncolumn,&errmsg );
if (SQLITE_OK != ret)
{
printf("exec失败:%s\n",errmsg);
sqlite3_free(errmsg);
return;
}
if (nrow == 0)
{
sprintf(str, "insert into reg_show values('%s','%s')","root","123456");
ret = sqlite3_exec(db, str, NULL, NULL, &errmsg);
if(ret != SQLITE_OK)
{
printf("exec 失败 %s\n", errmsg);
return;
}
}
while (1)
{
int cmd;
int ret = read(client_socket, &cmd,sizeof(int));
if (-1 == ret)
{
perror("read失败");
return ;
}
if (0 == ret)
{
break;
}
switch(cmd)
{
case REG: // 注册
reg(cmd, client_socket);
break;
case LOG:
mylog(cmd,client_socket);
break;
default:
break;
}
}
sqlite3_close(db);
}
// 监听套接字
int init()
{
int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == listen_socket)
{
perror(“创建套接字失败”);
return -1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET; /* Internet地址族 */
addr.sin_port = htons(PORT); /* 端口号 */
addr.sin_addr.s_addr = htonl(INADDR_ANY); /* IP地址, 绑定本地的所有ip地址*/
int opt = 1;
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)); //端口复用
int ret = bind(listen_socket, (const struct sockaddr *)&addr, sizeof(addr));
if(-1 == ret)
{
perror("绑定失败");
return -1;
}
// 3、监听套接字
ret = listen(listen_socket, 5);
if(-1 == ret)
{
perror("监听失败");
return -1;
}
return listen_socket;
}
// 通信套接字
int myAccept(int listen_socket)
{
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len);
if (-1 == client_socket)
{
perror(“accept 失败”);
return -1;
}
printf (“客户端的 ip = %s, 端口 = %d\n”, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
return client_socket;
}
int main(int argc, char **argv)
{
int listen_socket = init();
if (-1 == listen_socket)
return;
while (1)
{
long client_socket = myAccept(listen_socket);
if (-1 == client_socket)
{
continue;
}
// 开辟线程为客户端服务
pthread_t thread;
pthread_create(&thread, NULL, handl_client, (void *)client_socket);
pthread_detach(thread); // 线程分离
}
close(listen_socket);
return 0;
}