上次我们谈到实现简单聊天室的程序,其实大概流程在上一篇博客已经有讲清楚了,接下来就是贴代码的事情了。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <mysql.h>
#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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <time.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#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.退出");
}
}
界面总体来说还是有些丑陋,不过逻辑没问题就行了,就这样,以后还会所修改