聊天室服务器

#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sqlite3.h>
#include “chat.h”
#include <sys/stat.h>
#include <fcntl.h>
#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;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值