利用C/S模型实现简单聊天室

    上次我们谈到实现简单聊天室的程序,其实大概流程在上一篇博客已经有讲清楚了,接下来就是贴代码的事情了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "myQQ.h"
#define SERV_PORT				5678		//服务器端端口


MYSQL mysql;

//处理发送群聊消息请求
void Send_gmessage(request buf,b_data *back_data)
{
	MYSQL_RES	*res = NULL;
	MYSQL_ROW	rows;
	int rc,i,fields;
	char query_str[200];
	int row;
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"select * from relationinfo where name2='%s'",buf.recv_user);	//找到此群聊中所有成员,规定关系信息表中群聊在字段2
	
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	res = mysql_store_result(&mysql);
	fields = mysql_num_fields(res);
	row = mysql_num_rows(res);
	char ptr[row][20];
	for(i = 0;i < row;i++) {
		rows = mysql_fetch_row(res);
		memset(ptr[i],0,20);
		strcpy(ptr[i],rows[0]);
	}
		
	

	//对每个除了自己以外的成员发送消息
	for(i = 0;i < row;i++) {
		if(strcmp(ptr[i],buf.send_user)) {
			memset(query_str,0,strlen(query_str));
			sprintf(query_str,"select * from userinfo where name='%s'",ptr[i]);
			rc = mysql_real_query(&mysql,query_str,strlen(query_str));

			//判断对方是否离线
			res = mysql_store_result(&mysql);
			fields = mysql_num_fields(res);
			rows = mysql_fetch_row(res);

			if(rows[3][0] - '0' == 0) {
				back_data->cnt = 1;
				break;
			}
			
			int	recv_fd = rows[2][0] - '0';
		
			//将消息写入群聊天记录表中
			memset(query_str,0,strlen(query_str));
			sprintf(query_str,"insert into recordinfo(send_user,recv_user,type,data) values('%s','%s',%d,'%s')",buf.send_user,buf.recv_user,42,buf.data);
			rc = mysql_real_query(&mysql,query_str,strlen(query_str));

			//接收方存在且在线
			back_data->cnt = 1;
			b_data auf;
			memset(&auf,0,sizeof(auf));
			auf.type = 42;

			strcpy(auf.ar[0].send_user,buf.send_user);
			strcpy(auf.ar[0].recv_user,buf.recv_user);
			auf.ar[0].type = 2;
			strcpy(auf.ar[0].data,buf.data);
			printf("%s------->>>>%s\n",buf.send_user,buf.data);
			send(recv_fd,&auf,sizeof(b_data),0);	//发送消息
		}
	}

}


//处理发送私聊消息请求
void Send_message(request buf,b_data *back_data)
{
	MYSQL_RES	*res = NULL;
	MYSQL_ROW	rows;
	int rc,i,fields;
	char query_str[200];
	int recv_fd;
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"select * from userinfo where name='%s'",buf.recv_user);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	
	//判断对方是否离线
	res = mysql_store_result(&mysql);	
	fields = mysql_num_fields(res);
	rows = mysql_fetch_row(res);

	if(rows[3][0] - '0'== 0) {
		back_data->cnt = 1;				//搁置请求,等对方上线再发送
		return;
	}

	recv_fd = atoi(rows[2]);
	printf("recv_fd = %d\n",recv_fd);

	//将消息写入聊天记录表中
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"insert into recordinfo(send_user,recv_user,type,data) values('%s','%s',%d,'%s')",buf.send_user,buf.recv_user,41,buf.data);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));

	//接收方存在且在线
	back_data->cnt = 1;
	b_data auf;
	memset(&auf,0,sizeof(b_data));
	auf.type = 41;
	
	strcpy(auf.ar[0].send_user,buf.send_user);
	strcpy(auf.ar[0].recv_user,buf.recv_user);
	auf.ar[0].type = 1;
	strcpy(auf.ar[0].data,buf.data);
	send(recv_fd,&auf,sizeof(b_data),0);//发送消息


}

//处理删除好友请求
void Delete_Friend(request buf,b_data *back_data)
{
	MYSQL_RES	*res = NULL;
	MYSQL_ROW	rows;
	int rc,i,fields;
	int row;
	char query_str[200];					//存放mysql语句
	int recv_fd;
	//判断双方是否为好友
	sprintf(query_str,"select * from relationinfo where name1='%s' and name2='%s'",buf.send_user,buf.recv_user);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc != 0) {
		back_data->cnt = 0;					//说明双方不是好友了
		puts("1");
		return;	
	}
	printf("%s %s\n",buf.send_user,buf.recv_user);
	
	res = mysql_store_result(&mysql);
	mysql_free_result(res);
	
	
	//从关系信息表中删除双方好友信息
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"delete from relationinfo where name1='%s' and name2='%s'",buf.send_user,buf.recv_user);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc != 0) 
		printf("%s\n",mysql_error(&mysql));
	
	res = mysql_store_result(&mysql);

	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"delete from relationinfo where name1='%s' and name2='%s'",buf.recv_user,buf.send_user);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc != 0) 
		printf("%s\n",mysql_error(&mysql));
	back_data->cnt = 1;

}

//处理创建群聊请求
void Create_Group(request buf,b_data *back_data)
{
	MYSQL_RES	*res = NULL;
	
	int rc,i,fields;
	int rows;
	char query_str[200];
	int recv_fd;
	//判断是否存在此群聊
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"select * from relationinfo where name2='%s'",buf.data);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	res = mysql_store_result(&mysql);
	rows = mysql_num_rows(res);

	//判断该群聊是否存在
	if(rows != 0) {
		back_data->cnt = 0;
		return;
	}

	//若不存在则创建
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"insert into relationinfo(name1,name2,power) values('%s','%s',%d)",buf.send_user,buf.data,1);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc != 0) {
		back_data->cnt = 0;
		return;
	}
	back_data->cnt = 1;

}

//处理添加好友请求
void Add_Friend(request buf,b_data * back_data)
{
	
	MYSQL_RES	*res = NULL;
	MYSQL_ROW	rows;
	int rc,i,fields;
	int row;
	char query_str[200];					//存放mysql语句
	int recv_fd;
	//判断双方是否为好友
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"select * from relationinfo where name1='%s' and name2='%s'",buf.send_user,buf.recv_user);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc == 0) {
		back_data->cnt = 0;					//说明双方已经是好友了
		return;	
	}

	//判断对方是否离线
	mysql_store_result(&mysql);
	memset(query_str,0,sizeof(strlen(query_str)));
	sprintf(query_str,"select * from userinfo where name='%s'",buf.recv_user);
	//从用户信息表中获取接收方信息
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc != 0) {								//说明该用户不存在
		back_data->cnt = 0;
		return;
	}

	res = mysql_store_result(&mysql);
	row = mysql_num_rows(res);
	fields = mysql_num_fields(res);
	rows = mysql_fetch_row(res);
	if(strcmp(rows[3],"0") == 0)	{									//离线状态
		back_data->cnt = 1;				//搁置请求,等对方上线再发送
		return;
	}
	recv_fd = rows[2][0] - '0';
	//接收方存在且在线
	back_data->cnt = 1;
	b_data auf;
	memset(&auf,0,sizeof(b_data));
	auf.type = 431;
	strcpy(auf.ar[0].send_user,buf.send_user);
	strcpy(auf.ar[0].recv_user,buf.recv_user);
	auf.ar[0].type = 3;
	strcpy(auf.ar[0].data,buf.data);
	send(recv_fd,&auf,sizeof(b_data),0);//发送请求

}
//处理查看群聊天记录请求
//参数:用户名,群名称
//反馈数据:返回该群聊的聊天记录,存入back_data中
void View_grecord(request buf,b_data *back_data)
{
	MYSQL_RES	*res = NULL;
	MYSQL_ROW	rows;
	int row;
	char query_str[200];					//存放mysql语句的字符串数组
	int rc,i,fields;
	int count = 0;
	//在表中查找所有与该群聊有关的聊天记录

	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"select * from recordinfo where recv_user='%s'",buf.recv_user);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc != 0) {
		printf("error:%s",mysql_error(&mysql));
	}

	res = mysql_store_result(&mysql);
	row = mysql_num_rows(res);
	fields = mysql_num_fields(res);
	while((rows = mysql_fetch_row(res))) {
		strcpy(back_data->ar[count].send_user,rows[0]);
		strcpy(back_data->ar[count].recv_user,rows[1]);
		back_data->ar[count].type = 2;
		strcpy(back_data->ar[count].data,rows[4]);
		count++;
	}

}	
//处理查看私人聊天记录请求
//参数;用户名,好友名
//反馈数据:返回该用户与该好友的聊天记录信息,存入back_data中
void View_record(request buf,b_data *back_data)
{
	MYSQL_RES	*res = NULL;
	MYSQL_ROW	rows;
	int row;
	char query_str[200];					//存放mysql语句的字符串数组
	int rc,i,fields;
	int count = 0;
	//在表中查找所有与该用户和该好友有关的聊天记录

	char *name1 = buf.send_user;
	char *name2 = buf.recv_user;
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"select * from recordinfo where send_user='%s' or recv_user='%s'",name1,name1);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc != 0) {
		printf("error:%s",mysql_error(&mysql));
	}

	res = mysql_store_result(&mysql);
	row = mysql_num_rows(res);
	fields = mysql_num_fields(res);
	while((rows = mysql_fetch_row(res))) {
			if(strcmp(rows[0],name1) == 0 && strcmp(rows[1],name2) == 0) {
				strcpy(back_data->ar[count].send_user,rows[0]);
				strcpy(back_data->ar[count].recv_user,rows[1]);
				back_data->ar[count].type = 1;
				strcpy(back_data->ar[count].data,rows[4]);
				count++;
			}
				
			else if(strcmp(rows[0],name2) == 0 && strcmp(rows[1],name1) == 0) {
				strcpy(back_data->ar[count].send_user,rows[0]);
				strcpy(back_data->ar[count].recv_user,rows[1]);
				back_data->ar[count].type = 1;
				strcpy(back_data->ar[count].data,rows[4]);
				count++;
			}
	}
}

//显示某个用户是否在线
//参数:用户名
//若在线,返回1,若不在线,返回2
/*int Online(char *name)
{
	char query_str[200];
	memset(query_str,0,strlen(query_str));
	sprintf
*/



//处理显示所有好友请求
//参数:用户名
//反馈数据:返回所有该用户的好友信息,存入back_data中
void display_all(request buf,b_data *back_data)
{
	MYSQL_RES	*res = NULL;
	MYSQL_ROW	rows;
	int row;
	char query_str[200];					//存放mysql语句的字符串数组
	int rc,i,fields;
	char ptr[100][20];						//反馈类型
	int count = 0;
	//在表中查找所有与该用户名是好友的用户
	

	char *name = buf.send_user;
	int fd = buf.fd;
	
	memset(query_str,0,strlen(query_str));
	sprintf(query_str,"select *%c from relationinfo",' ');
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	if(rc != 0) {
		printf("mysql_read_query():%s\n",mysql_error(&mysql));
	}
	
	res = mysql_store_result(&mysql);
	if(res == NULL) {
		printf("error:%s",mysql_error(&mysql));
	}
	row = mysql_num_rows(res);
	fields = mysql_num_fields(res);
	while((rows = mysql_fetch_row(res))) {
			if(strcmp(rows[0],buf.send_user) == 0)
				strcpy(back_data->str[count++],rows[1]);
	}
	
}
			

//处理登录请求
//参数:用户名name 密码 passwd
//反馈数据:在用户文件里面找到则返回int 1,否则返回0
int login_server(request buf)
{
	MYSQL_RES *res = NULL;
	int rows;
	char query_str[200];						//存放mysql语句的字符串数组
	int rc;
	int feedback = 0;							//反馈类型
	//在文件中查找是否存在该用户名以及对应的密码
	
	char *name = buf.send_user;
	char *passwd = buf.data;
	int fd = buf.fd;				
	memset(query_str,0,strlen(query_str));
	printf("name = %s,passwd =%s\n",name,passwd);
	sprintf(query_str,"select * from userinfo where name='%s' and passwd='%s'",name,passwd);
	
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	memset(query_str,0,strlen(query_str));		//清空语句
	res = mysql_store_result(&mysql);
	rows = mysql_num_rows(res);
	
	if(rows != 0) {
		feedback = 1;
		//登录成功,将用户信息表中用户在线状态改为在线,套接字改为此次登录的所使用的套接字
		sprintf(query_str,"update userinfo set state=%d,fd=%d where name='%s'",1,fd,name);
		mysql_store_result(&mysql);
		rc = mysql_real_query(&mysql,query_str,strlen(query_str));
		if(rc != 0) {
			printf("%s",mysql_error(&mysql));
			printf("登录写入失败\n");
		}
		memset(query_str,0,strlen(query_str));
	}
	return feedback;	
}

//处理注册请求
//参数:新用户名name新密码 passwd
//反馈数据:注册成功返回1,否则返回0
int register_server(request buf)
{
	char query_str[200];
	int feedback = 0;							//反馈类型
	//在文件中查找是否存在该用户名
	int rc;
	
	char *name = buf.send_user;
	char *passwd = buf.data;
	int fd = buf.fd;

	sprintf(query_str,"select * from userinfo where='%s'",name);
	rc = mysql_real_query(&mysql,query_str,strlen(query_str));
	memset(query_str,0,strlen(query_str));
	if(rc != 0) {
		feedback = 1;
		//注册成功,将新用户信息写入用户信息表
		sprintf(query_str,"insert into userinfo values('%s','%s',%d,%d)",name,passwd,fd,0);
		rc = mysql_real_query(&mysql,query_str,strlen(query_str));
		if(rc != 0) 
			printf("注册写入失败\n");
		memset(query_str,0,strlen(query_str));
	}
	return feedback;	
}

//处理所有请求的函数
//参数,客户端套接字
//反馈数据:无
void *handle_all(void *fd)					//int fd
{
	
	pthread_t thid;
	request buf;
	b_data back_data;
	int conn_fd = *(int *)fd;
	while(1) {
		int ret = recv(conn_fd,&buf,sizeof(buf),0);
		if(ret < 0) {
			perror("recv:");
		}
		else if(ret == 0) 
			pthread_exit(0);
		switch(buf.type) {
			case 0100:
				//处理登录请求
				memset(&back_data,0,sizeof(b_data));
				buf.fd = conn_fd;
				back_data.cnt = login_server(buf);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;
			case 0110:
				//处理注册请求
				memset(&back_data,0,sizeof(b_data));
				back_data.cnt = register_server(buf);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;
			case 0240:
				//处理显示所有好友请求
				printf("%s\n",buf.send_user);
				memset(&back_data,0,sizeof(b_data));
				display_all(buf,&back_data);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;
			case 0250:
				//处理查看私人聊天记录请求
				printf("%s %s\n",buf.send_user,buf.recv_user);
				memset(&back_data,0,sizeof(b_data));
				View_record(buf,&back_data);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;
			case 0370:
				//处理查看群聊天记录请求
				printf("%s %s\n",buf.send_user,buf.recv_user);
				memset(&back_data,0,sizeof(b_data));
				View_grecord(buf,&back_data);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;
			case 0310:
				//处理创建群聊请求
				printf("%s %s\n",buf.send_user,buf.data);
				memset(&back_data,0,sizeof(b_data));
				Create_Group(buf,&back_data);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;
			case 0210:
				//处理添加好友请求
				printf("%s %s\n",buf.send_user,buf.recv_user);
				memset(&back_data,0,sizeof(b_data));
				Add_Friend(buf,&back_data);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;
			case 0220:
				//处理删除好友请求
				printf("%s %s\n",buf.send_user,buf.recv_user);
				memset(&back_data,0,sizeof(b_data));
				Delete_Friend(buf,&back_data);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;
			case 0200:
				//处理发送消息请求
				printf("%s %s\n",buf.send_user,buf.recv_user);
				memset(&back_data,0,sizeof(b_data));
				Send_message(buf,&back_data);
				send(conn_fd,&back_data,sizeof(b_data),0);
			case 0300:
				//处理发送群聊消息请求
				printf("send_user = %s recv_user = %s\n",buf.send_user,buf.recv_user);
				memset(&back_data,0,sizeof(b_data));
				Send_gmessage(buf,&back_data);
				send(conn_fd,&back_data,sizeof(b_data),0);
				break;

			default:
				//
				break;
		}
	}

}

int main(int argc,char *argv[])
{
	if(mysql_init(&mysql) == NULL) {					//分配和初始化mysql对象
		printf("mysql_init():%s\n",mysql_error(&mysql));
		return -1;
	}
														//连接
	mysql_real_connect(&mysql,NULL,username,passwd,name,0,NULL,0);
	struct sockaddr_in serv_addr,cli_addr;
	int sock_fd = socket(AF_INET,SOCK_STREAM,0);		//创建TCP套接字
	if(sock_fd < 0) {
		perror("socket :");
	}

	//初始化服务器端地址结构
	memset(&serv_addr,0,sizeof(struct sockaddr_in));
	serv_addr.sin_family = AF_INET;						
	serv_addr.sin_port = htons(SERV_PORT);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	//将套接字绑定到本地端口
	if(bind(sock_fd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr_in)) < 0) {
			perror("bind:");
	}

	//转化为监听套接字
	if(listen(sock_fd,100) < 0) {
		perror("listen:");
	}
	int cli_len = sizeof(cli_addr);
	int *conn_fd;
	while(1) {
		conn_fd = (int *)malloc(sizeof(int));
		//接受来自客户端的连接请求
		*conn_fd = accept(sock_fd,(struct sockaddr *)&cli_addr,&cli_len);
		printf("welcome:%d\n",*conn_fd);
		if(conn_fd < 0) {
			perror("accept:");
		}

		//创建一个线程去处理连接
		pthread_t thid;
		pthread_create(&thid,NULL,handle_all,(void *)conn_fd);
	}
	return 0;
}

这是服务器的部分代码,接下来就是客户端了,我采用的是主线程实现功能,开一个线程去接受来自服务器的回馈,这样就可以实现接受消息的请求了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "myQQ.h"
#define PORT		5678

char *user;							//记录此时登录的用户
b_data back_data;
int count;
pthread_mutex_t mutex;
char *passwd;
char group[20];						//记录当前正在聊天的群聊	
char friend[20];					//记录当前正在聊天的好友
struct record cr[50];				//存放所有被动接收到的消息
int cnt = 0;						//存放被动接收到的消息的数量


//创建接受服务器反馈结果的线程
void *fback(void *arg)
{
	int conn_fd = *(int *)arg;	
	int num = 0;
	while(1) {
		if((num += recv(conn_fd,&back_data,sizeof(back_data),0)) < 0) {
			perror("recv");
		}
		if(num == sizeof(back_data)) {						//确保接收到完整的结构体
			
			if(back_data.type == 431)	{					//是接收到的消息
				printf("用户%s请求加您为好友\n",back_data.ar[0].send_user);
				memcpy((void *)&cr[cnt++],(void *)&back_data.ar[0],sizeof(struct record));
			}
			else if(back_data.type == 41) {					//正在和此好友聊天
				if(strcmp(friend,back_data.ar[0].send_user) == 0) {
					printf("%s:%-50s\n",friend,back_data.ar[0].data);
					back_data.flag = 1;
				}
				else {										//没有和此好友聊天
					printf("您有一条来自好友%s的新消息,请及时查看\n",back_data.ar[0].send_user);
					memcpy((void *)&cr[cnt++],(void *)&back_data.ar[0],sizeof(struct record));
				}
			}
			else if(back_data.type == 42) {					//正在水群
				if(strcmp(group,back_data.ar[0].recv_user) == 0) {	
					printf("%s:%-50s\n",back_data.ar[0].send_user,back_data.ar[0].data);
					back_data.flag = 1;
				}
				else {										//没有水群
					printf("您有一条来自群聊%s的新消息,请及时查看\n",back_data.ar[0].recv_user);
					memcpy((void *)&cr[cnt++],(void *)&back_data.ar[0],sizeof(struct record));
				}
			}
			count = 1;					//经过处理之后将是否接收到该消息标志置为1
			num = 0;
			
		}
	}
}


int main(int argc,char *argv[])
{
	struct sockaddr_in serv_addr;
	int sock_fd;
	request buf;
	sock_fd = socket(AF_INET,SOCK_STREAM,0);
	if(sock_fd < 0) {
		perror("socket:");
	}

	//初始化服务器端口与地址
	memset(&serv_addr,0,sizeof(struct sockaddr_in));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(PORT);	//服务器端口
	inet_pton(AF_INET,argv[1],&serv_addr.sin_addr);	
	
	//连接服务器
	connect(sock_fd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr));
	if(sock_fd < 0) {
		perror("connect:");
	}
	pthread_t thid;
	pthread_create(&thid,NULL,fback,(void *)&sock_fd);
	
	//选择功能
	printf("1.登录\n2.注册\n3.退出\n");
	char choice;
	while(scanf("%c",&choice) && choice != '3') {
		switch(choice) {
			case '1':
				memset(&buf,0,sizeof(buf));
				buf.type = 0100;
				printf("请输入用户名:");
				scanf("%s",buf.send_user);
				user = buf.send_user;
				printf("请输入密码:");
				scanf("%s",buf.data);
				passwd = buf.data;					//使用全局变量保存登陆者的信息以便在其他函数中调用
				buf.flag = 0;
				
				memset(&back_data,0,sizeof(back_data));
				count = 0;							//接收标志置为0
				send(sock_fd,&buf,sizeof(buf),0);	//发送请求
			
				while(1) {
					if(count == 1 && back_data.cnt == 1) {
						user = buf.send_user;
						puts("登陆成功!");
						Main_menu(sock_fd);								//进入管理界面
						break;
					}
					else if(count == 1 && back_data.cnt == 0) {
						puts("密码错误");
						break;
					}
				}
				break;
			case '2':
				buf.type = 0110;
				printf("请输入新的用户名:");
				scanf("%s",buf.send_user);
				printf("请输入新的密码:");
				scanf("%s",buf.data);
				buf.fd = sock_fd;
				buf.flag = 0;
				
				memset(&back_data,0,sizeof(back_data));
				count= 0;							//接收标志置为0
				send(sock_fd,&buf,sizeof(buf),0);	//发送请求
				
				while(1) {
					if(count == 1 && back_data.cnt == 1) {
						printf("注册成功");
						break;
					}
					else if(count == 1 && back_data.cnt == 0)
						puts("注册失败");
				}
				break;
			default:
				break;
		}
		while(getchar() != '\n');
		printf("1.登录\n2.注册\n3.退出\n");
	}
	return 0;
}

//管理界面,包括好友管理,群聊管理,消息管理,账号管理
void Main_menu(int fd)
{
	int choice;
	request buf;
	printf("1.好友管理\n2.群管理\n3.消息管理\n4.账号管理\nq.返回上一层\n");
	while(scanf("%d",&choice) && choice != 'q') {
		switch(choice) {
			case 1:
				Friend_Manage(fd);					//好友管理
				break;
			case 2:
				Group_Manage(fd);					//群管理
				break;
			case 3:
				News_Manage(fd);					//消息管理
				break;
			case 4:
	//			Account_Manage(fd);					//账号管理
				break;
			default:
				printf("请输入正确的选项\n");
		}
		printf("1.好友管理\n2.群管理\n3.消息管理\n4.账号管理\nq.返回上一层\n");
		while(getchar() != '\n');
	}
	memset(user,0,20);
	return;
}

//好友管理界面
void Friend_Manage(int fd)
{
	//显示所有好友
	request buf;
	buf.type = 0240;
	strcpy(buf.send_user,user);
	buf.fd = fd;
	buf.flag = 0;
	int i;

	count = 0;
	memset(&back_data,0,sizeof(back_data));
	send(fd,&buf,sizeof(buf),0);					//发送请求
	
	while(1) {
		if(count == 1 && back_data.str[0][0] != '\0') {
			for(i = 0;back_data.str[i][0] != '\0';i++)
				printf("%s\n",back_data.str[i]);
			break;
		}
		else if(count == 1 && back_data.str[0][0] == '\0') {
			printf("您目前还没有好友\n");
			break;
		}
	}

	printf("1.私聊\n2.添加好友\n3.删除好友\n4.查询好友\n5.查看聊天记录\nq.退出\n");
	int choice;
	int choice2;
	char friend_name[20];
	memset(&buf,0,sizeof(buf));
	while(scanf("%d",&choice) && choice != 'q') {
		switch(choice) {
			case 1:
				printf("请输入好友昵称:");
				scanf("%s",buf.recv_user);
				//显示之前五十条聊天记录
				memset(friend,0,20);
				strcpy(friend_name,buf.recv_user);
				buf.type = 0250;
				strcpy(buf.send_user,user);
				buf.fd = fd;
				buf.flag = 0;
				

				memset(&back_data,0,sizeof(back_data));	//清空接收结构体
				count = 0;								//将接收标志置为0
				send(fd,&buf,sizeof(buf),0);			//发送查看聊天记录请求

				while(1) {
					if(count == 1 && back_data.ar[0].data[0] != '\0') {
						for(i = 0;back_data.ar[i].data[0] != '\0';i++) {
							if(strcmp(back_data.ar[i].send_user,user) == 0)
								printf("%50s:%s\n",back_data.ar[i].data,back_data.ar[i].recv_user);
							else
								printf("%s:%-50s\n",user,back_data.ar[i].data);
						}
						break;
					}
					else if(count == 1 && back_data.ar[0].data[0] == '\0')
						break;
				}

				//发送消息
				printf("1.发送消息\nq.退出\n");
				strcpy(friend,buf.recv_user);			//设置正在聊天的好友
				while(scanf("%d",&choice2) && choice2 != 'q') {
					switch(choice2) {
						case 1:
							memset(&buf,0,sizeof(buf));		//清空请求结构体
							printf("请输入你想发送的内容:");
							scanf("%s",buf.data);
							buf.type = 0200;
							strcpy(buf.send_user,user);
							buf.fd = fd;
							strcpy(buf.recv_user,friend_name);
							buf.time = time(NULL);
							int flag = 0;

							count = 0;					//将接收标志置0
							memset(&back_data,0,sizeof(back_data));	//清空接收结构体
							send(fd,&buf,sizeof(buf),0);			//发送消息请求
							
							break;
						default:
							printf("请输入正确的选项\n");
							break;
					}
					printf("1.发送消息\nq.退出\n");
				}
				memset(friend,0,20);				//将正在聊天的好友置0
				break;
			case 2:
				//添加好友
				memset(friend_name,0,20);
				memset(&buf,0,sizeof(buf));
				memset(&back_data,0,sizeof(b_data));
				
				printf("请输入好友昵称:");
				scanf("%s",friend_name);
				printf("请输入验证信息:");
				scanf("%s",buf.data);
				
				buf.time = time(NULL);
				buf.type = 0210;
				strcpy(buf.send_user,user);
				strcpy(buf.recv_user,friend_name);
				buf.fd = fd;
				buf.flag = 0;

				count = 0;
				memset(&back_data,0,sizeof(back_data));
				send(fd,&buf,sizeof(buf),0);
				while(1) {
					if(count == 1 && back_data.cnt == 1) { 
						printf("请求发送成功!\n");
						break;
					}
					else if(count == 1 && back_data.cnt  == 0) {
						printf("添加失败!\n");
						break;
					}
				}
				break;
			case 3:
				//删除好友
				memset(friend_name,0,20);
				memset(&buf,0,sizeof(buf));
				memset(&back_data,0,sizeof(b_data));

				printf("请输入欲删除好友昵称:");
				scanf("%s",buf.recv_user);

				buf.type = 0220;
				strcpy(buf.send_user,user);
				buf.fd = fd;
				buf.flag = 0;

				count = 0;
				memset(&back_data,0,sizeof(back_data));
				send(fd,&buf,sizeof(buf),0);
				while(1) {
					if(count == 1 && back_data.cnt == 1) {
						printf("删除成功");
						break;
					}
					else if(count == 1 && back_data.cnt == 0) {
						printf("删除失败");
						break;
					}
				}
				break;
			case 4:
				break;
			case 5:
				break;
			default:
				printf("请输入正确选项");
		}
		printf("1.私聊\n2.添加好友\n3.删除好友\n4.查询好友\n5.查看聊天记录\nq.退出\n");
	}
}

//消息管理界面
void News_Manage(int fd)
{
	int i;
	char choice;
	char choice2;
	char choice3;
	char choice4;
	char friend_name[20];					//存放好友姓名的字符串数组
	request buf;

	memset(friend_name,0,20);
	while(getchar() != '\n');
	printf("1.私聊\n2.群聊\n3.系统通知\nq.退出\n");
	while(scanf("%c",&choice) && choice != 'q') {
		switch(choice) {
			case '1':
				
				for(i = 0;i < cnt;i++) {
					if(cr[i].type == 1) 
						printf("%s %s\n",cr[i].send_user,asctime((localtime(&cr[i].time))));
				}
				printf("1.我要回复\nq.算了懒得回了(退出)\n");
				//进入私聊界面
				while(scanf("%c",&choice3) && choice3 != 'q') {
					switch(choice3) {
						case '1':
							Chat_Friend(fd);
							break;
					}
					while(getchar() != '\n');
					printf("1.我要回复\nq.算了懒得回了(退出)\n");
				}
				break;

			case '2':
				for(i = 0;i < cnt;i++) {
					if(cr[i].type == 2) 
						printf("%s %s\n",cr[i].send_user,asctime((localtime(&cr[i].time))));
				}
				
				
				break;
			
			case '3':
				//显示所有系统通知和好友请求
				for(i = cnt-1;i >= 0;i--) {
					if(cr[i].type == 3) 
						printf("%s %s\n",cr[i].send_user,asctime((localtime(&cr[i].time))));
						printf("%s\n",cr[i].data);
				}
	//			printf("1.我要处理\nq.算了就当没看见(退出)\n");
	//			for(i = 0;i < cnt;i++) {
	//				if(ar[i].type == 31)
				break;
					
			default:

				printf("请输入正确的选项\n");
				break;
		}
		while(getchar() != '\n');
		printf("1.私聊\n2.群聊\n3.系统通知\nq.退出\n");
	}
}

//与好友私聊界面
void Chat_Friend(int fd)
{
	request buf;
	char friend_name[20];
	int i;
	char choice2;
	
	memset(friend_name,0,20);
	printf("请输入好友昵称:");
	scanf("%s",buf.recv_user);
	//显示之前五十条聊天记录
	memset(friend,0,20);
	strcpy(friend,buf.recv_user);
	printf("%s\n",friend);
	strcpy(friend_name,buf.recv_user);
	buf.type = 0250;
	strcpy(buf.send_user,user);
	buf.fd = fd;
	buf.flag = 0;


	memset(&back_data,0,sizeof(back_data));	//清空接收结构体
	count = 0;								//将接收标志置为0
	send(fd,&buf,sizeof(buf),0);			//发送查看聊天记录请求

	while(1) {
		if(count == 1 && back_data.ar[0].data[0] != '\0') {
			for(i = 0;back_data.ar[i].data[0] != '\0';i++) {
				if(strcmp(back_data.ar[i].send_user,user) == 0)
					printf("%50s:%s\n",back_data.ar[i].data,back_data.ar[i].recv_user);
				else
					printf("%s:%-50s\n",user,back_data.ar[i].data);
			}
			break;
		}
		else if(count == 1 && back_data.ar[0].data[0] == '\0')
			break;
	}

	//发送消息
	printf("1.发送消息\nq.退出\n");
	while(getchar() != '\n');
	while(scanf("%c",&choice2) && choice2 != 'q') {
		switch(choice2) {
			case 1:
				memset(&buf,0,sizeof(buf));		//清空请求结构体
				printf("请输入你想发送的内容:");
				scanf("%s",buf.data);
				buf.type = 0200;
				strcpy(buf.send_user,user);
				buf.fd = fd;
				strcpy(buf.recv_user,friend_name);
				buf.time = time(NULL);
				int flag = 0;

				count = 0;					//将接收标志置0
				memset(&back_data,0,sizeof(back_data));	//清空接收结构体
				send(fd,&buf,sizeof(buf),0);			//发送消息请求

				break;
			default:
				printf("请输入正确的选项\n");
				break;
		}
		printf("1.发送消息\nq.退出\n");
	}
}

//群聊界面
void Chat_Group(int fd)
{
	request buf;
	int i;
	char choice2;
	memset(&buf,0,sizeof(buf));
	printf("请输入群聊名称:");
	scanf("%s",buf.recv_user);
	memset(group,0,20);

	//显示出群聊最近的聊天记录
	//初始化请求
	buf.type = 0370;
	strcpy(buf.send_user,user);
	buf.flag = 0;

	//发送请求
	count = 0;
	memset(&back_data,0,sizeof(b_data));
	send(fd,&buf,sizeof(buf),0);

	//显示该群聊天记录
	while(1) {
		if(count == 1 && back_data.ar[0].data[0] != '\0') {
			for(i = 0;back_data.ar[i].data[0] != '\0';i++) {
				if(strcmp(user,back_data.ar[i].send_user) == 0)
					printf("%50s:%s\n",user,back_data.ar[i].data);
				else
					printf("%s:%s\n",back_data.ar[i].send_user,back_data.ar[i].data);
			}
			break;
		}
		else if(count == 1 && back_data.ar[0].data[0] == '\0')
			break;
	}


	//发送消息
	printf("1.发送消息\nq.退出\n");
	strcpy(group,buf.recv_user);
	while(getchar() != '\n');				//清空缓冲区	
	while(scanf("%c",&choice2) && choice2 != 'q') {
		switch(choice2) {
			case '1':
				memset(&buf,0,sizeof(buf));		//清空请求结构体
				printf("请输入你想发送的内容:");
				scanf("%s",buf.data);
				buf.type = 0300;					//请求类型为群聊请求
				strcpy(buf.send_user,user);
				buf.fd = fd;
				strcpy(buf.recv_user,group);
				buf.time = time(NULL);
				int flag = 0;

				count = 0;					//将接收标志置0
				memset(&back_data,0,sizeof(back_data));	//清空接收结构体
				send(fd,&buf,sizeof(buf),0);			//发送消息

				break;
			default:
				printf("请输入正确的选项\n");
				break;
		}
		while(getchar() !='\n');
		printf("1.发送消息\nq.退出\n");
	}
	memset(group,0,20);


}
//群聊管理界面
void Group_Manage(int fd)
{
	request buf;
	char choice;
	int i;
	char create_group[20];
	while(getchar() != '\n');
	printf("1.群聊\n2.创建群\n3.解散群\n4.加入群\nq.退出\n");
	while(scanf("%c",&choice) && choice != 'q') {
		switch(choice) {
			//群聊
			case '1':
				Chat_Group(fd);
				break;
			//创建群
			case '2':
				printf("请输入要创建的群名称:");
				memset(create_group,0,20);
				scanf("%s",create_group);

				//初始化请求
				strcpy(buf.data,create_group);
				strcpy(buf.send_user,user);
				buf.type = 0310;

				//发送请求
				count = 0;
				memset(&back_data,0,sizeof(b_data));
				send(fd,&buf,sizeof(buf),0);
			
				while(1) {
					if(count == 1 && back_data.cnt == 1) {
						printf("您的群聊%s创建成功\n",create_group);
						break;
					}
					else if(count == 1 && back_data.cnt == 0) {
						printf("创建失败\n");
						break;
					}
				}
				break;
			default:
				printf("请输入正确的选项\n");
				break;
		}
		while(getchar() != '\n');			//清空缓冲区
		printf("1.群聊\n2.创建群\n3.解散群\n4.加入群\nq.退出");
	}
}

界面总体来说还是有些丑陋,不过逻辑没问题就行了,就这样,以后还会所修改

你可能感兴趣的:(利用C/S模型实现简单聊天室)