要求
实现一个简单的聊天室,具有私聊,群聊和传送文件的基本功能,以及一些小细节的实现。
头文件
#ifndef MY_CHAT_H
#define MY_CHAT_H
#include<pthread.h>
//倾听的最大数量
#define LISTENG 20
//端口
#define SERV_PORT 4508
#define MAX 1024
pthread_mutex_t mutex_cli;
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_cond_t cond_cli;
typedef struct{
int t;
long size;
int cont;
int type;
int type1;
int send_fd;
int recv_fd;
int line;
int relation;//0 申请 1 好友 -1 黑名单
char send_id[4];
char recv_id[4];
char send_name[4];
char recv_name[4];
char read_buf[1024];
char write_buf[1024];
char buf[1024];
}bag;
typedef struct{
int id[500];
int fri_id[500];
int buf_num;
char buf[500][1024];
char time[500][100];
}fri_mes;
typedef struct{
int gro_id;//群号
int id[500];//发言人的账号
int number;//记录条数
char buf[500][1024];//聊天记录
char time[500][100];//时间
}gro_mes;
typedef struct{
int gro_id;
char gro_name[4];
int gro_mem_id;
int gro_chmod;//群主 2 管理员 1 普通成员 0
}gro;
typedef struct friend{
int fri_number;
char fri_name[500][4];
int fri_id[500];
int fri_line[500];
}fri;
typedef struct {
int id[500];
int chmod[500];
int number;
}group;
typedef struct BOX {
//文件数量
int file_number;
//文件名字
char file_name[500][100];
//文件发送者账号
int file_id[500];
//接收消息的人的账号
int recv_id;
//发送消息人的账号
int send_id[500];
//发送好友请求人的账号
int plz_id[500];
//发送的消息
char read_buf[500][MAX];
//发送的请求
char write_buf[500][100];
//消息数量
int talk_number;
//请求数量
int friend_number;
//群里发送消息的人
int send_id1[500];
//消息内容
char message[500][MAX];
//群消息数量
int number;
//群号
int group_id[500];//消息的群号
struct BOX *next;
} BOX;
BOX *box_head;
BOX *box_tail;
#endif
服务端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <mysql.h>
#include <stdlib.h>
#include"my_chat.h"
#include <sys/epoll.h>
#include <termios.h>
#include<time.h>
#include <sys/stat.h>
#include <fcntl.h>
MYSQL mysql;
int sock_init()
{
int sock_fd;
struct sockaddr_in serv_addr;
sock_fd=socket(AF_INET,SOCK_STREAM | SOCK_NONBLOCK,0);
if(sock_fd<0)
{
perror("socket failed");
return -1;
}
int optval=1;
if(setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,(void *)&optval,sizeof(int))<0)
{
perror("setsockopt failed");
return -1;
}
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 failed");
return -1;
}
if(listen(sock_fd,LISTENG)<0)
{
perror("listen failed");
return -1;
}
printf("服务端监听中...\n");
return sock_fd;
}
void mysql_init1()
{ //句柄
if(NULL == mysql_init(&mysql)){
perror("mysql_init failed");
return;
}
//初始化数据库
if(mysql_library_init(0, NULL, NULL) != 0){
perror("mysql_library_init failed");
return;
}
//连接数据库
if(NULL == mysql_real_connect(&mysql, "127.0.0.1", "root", "hh123456789", "try", 0, NULL, 0)){
perror("mysql_real_connect failed");
return;
}
//设置中文字符集
if(mysql_set_character_set(&mysql, "utf8") < 0){
perror("mysql_set_character_set failed");
return;
}
printf("连接mysql数据库成功!\n");
}
int login(bag *recv_bag)
{
printf("检查信息中...\n");
bag *bag1=recv_bag;
int ret;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
memset(sql,0,1280);
sprintf(sql,"select * from 身份信息 where id = '%s' and passwd ='%s' and line = 0",bag1->send_id,bag1->read_buf);
ret=mysql_query(&mysql,sql);
if(!ret)
{
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row)
{
memset(sql,0,1280);
sprintf(sql,"update 身份信息 set line = 1 , sockfd = %d where id = '%s'",bag1->recv_fd,bag1->send_id);
ret=mysql_query(&mysql,sql);
memset(bag1->write_buf,0,1024);
strcpy(bag1->write_buf,"login successfully");
strcpy(bag1->send_name,row[1]);
if(ret<0)
{
perror("login failed");
exit(1);
}
ret=send(bag1->recv_fd,bag1,sizeof(bag),0);
if(ret<0)
{
perror("send failed");
exit(1);
}
printf("login successfully\n");
mysql_free_result(result);
return 1;
}else{
strcpy(bag1->write_buf,"login failed");
send(bag1->recv_fd,bag1,sizeof(bag),0);
printf("login failed\n");
}
}else{
strcpy(bag1->write_buf,"login failed");
send(bag1->recv_fd,bag1,sizeof(bag),0);
printf("login failed\n");
}
return 0;
}
int resign(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
int j=100;
int ret;
MYSQL_RES *result=NULL;
MYSQL_ROW row;
memset(sql,0,1280);
sprintf(sql,"select * from 身份信息");
ret=mysql_query(&mysql,sql);
if(ret<0)
{
perror("mysql_query failed");
return -1;
}
result=mysql_store_result(&mysql);
while(row=mysql_fetch_row(result))
{
j++;
}
sprintf(bag1->send_id,"%d",j);
bag1->line=0;
pthread_mutex_lock(&mutex);
memset(sql,0,1280);
sprintf(sql,"insert into 身份信息 values('%s','%s','%s',%d,%d)",bag1->send_id,bag1->send_name,bag1->read_buf,bag1->line,bag1->recv_fd);
mysql_query(&mysql,sql);
ret=send(bag1->recv_fd,bag1,sizeof(bag),0);
if(ret<0)
{
perror("send failed");
pthread_mutex_unlock(&mutex);
return -1;
}
printf("注册成功!\n");
pthread_mutex_unlock(&mutex);
return 0;
}
int add_fri(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row,row1;
int t;
int ret;
BOX *box=box_head;
memset(sql,0,1280);
sprintf(sql,"select * from 身份信息 where id = '%s'",bag1->recv_id);
ret=mysql_query(&mysql,sql);
if(!ret){
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row==NULL)
{
strcpy(bag1->write_buf,"-2");
}else{
memset(sql,0,1280);
sprintf(sql,"select * from friend where id1 = '%s' and id2='%s' ",bag1->send_id,bag1->recv_id);
ret=mysql_query(&mysql,sql);
if(!ret){
result=mysql_store_result(&mysql);
row1=mysql_fetch_row(result);
if(row1){
t=atoi(row1[2]);
if(t==1){
strcpy(bag1->write_buf,"1");
}else if(t==-1)
{
strcpy(bag1->write_buf,"-1");
}else if(t==0){
strcpy(bag1->write_buf,"3");
}else{
strcpy(bag1->write_buf,"4");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
return 0;
}else{
printf("正在发送请求!\n");
pthread_mutex_lock(&mutex);
memset(sql,0,1280);
sprintf(sql,"insert into friend values('%s','%s',0)",bag1->send_id,bag1->recv_id);
ret=mysql_query(&mysql,sql);
if(ret<0)
{
perror("failed");
exit(1);
}
strcpy(bag1->write_buf,"0");
pthread_mutex_unlock(&mutex);
send(bag1->recv_fd,bag1,sizeof(bag),0);
if(atoi(row[3])==0){
while(box!=NULL)
{
if(box->recv_id==atoi(bag1->recv_id))
{
break;
}
box=box->next;
}
if(box==NULL)
{
box=(BOX *)malloc(sizeof(BOX));
box->friend_number=0;
box->number=0;
box->talk_number=0;
box->file_number=0;
box->next=NULL;
box->recv_id=atoi(bag1->recv_id);
box->plz_id[box->friend_number]=atoi(bag1->send_id);
box->friend_number++;
if(box_head==NULL)
{
box_head=box;
box_tail=box;
}else{
box_tail->next=box;
box_tail=box;
}
}else{
box->plz_id[box->friend_number]=atoi(bag1->send_id);
box->friend_number++;
}
}else{
bag1->send_fd=atoi(row[4]);
strcpy(bag1->write_buf,"0");
send(bag1->recv_fd,bag1,sizeof(bag),0);
bag1->type=18;
bag1->type1=1;
send(bag1->send_fd,bag1,sizeof(bag),0);
}
}
}else{
strcpy(bag1->write_buf,"4");
send(bag1->recv_fd,bag1,sizeof(bag),0);
}
}
}else{
strcpy(bag1->write_buf,"4");
send(bag1->recv_fd,bag1,sizeof(bag),0);
}
return 0;
}
int xiugai(bag *recv_bag)
{
bag *bag1=recv_bag;
int t=bag1->type1;
char sql[1280];
int ret;
pthread_mutex_lock(&mutex);
if(t==1){
memset(sql,0,1280);
sprintf(sql,"update 身份信息 set name = '%s' where id = '%s'",bag1->read_buf,bag1->send_id);
mysql_query(&mysql,sql);
printf("修改中...\n");
}else if(t==2){
memset(sql,0,1280);
sprintf(sql,"update 身份信息 set passwd = '%s' where id = '%s'",bag1->read_buf,bag1->send_id);
mysql_query(&mysql,sql);
printf("修改中...\n");
}
pthread_mutex_unlock(&mutex);
}
int deal(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
switch(bag1->type1)
{
case 1:
{
if(strcmp(bag1->read_buf,"tongyi")==0)
{
pthread_mutex_lock(&mutex);
memset(sql,0,1280);
sprintf(sql,"update friend set relation = 1 where id1 = '%s' and id2 = '%s'",bag1->recv_id,bag1->send_id);
mysql_query(&mysql,sql);
memset(sql,0,1280);
sprintf(sql,"insert into friend values('%s','%s',1)",bag1->send_id,bag1->recv_id);
mysql_query(&mysql,sql);
pthread_mutex_unlock(&mutex);
}else if(strcmp(bag1->read_buf,"jujue")==0){
memset(sql,0,1280);
sprintf(sql," delete from friend where relation = 0 and id1 ='%s' and id2 = '%s' ",bag1->recv_id,bag1->send_id);
mysql_query(&mysql,sql);
}
break;
}
}
}
int del_fri(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
char sql1[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
memset(sql,0,1280);
sprintf(sql,"select * from friend where id1 ='%s' and id2 = '%s'",bag1->send_id,bag1->recv_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row)
{
pthread_mutex_lock(&mutex);
memset(sql,0,1280);
sprintf(sql,"delete from friend where id1 = '%s' and id2 ='%s'",bag1->send_id,bag1->recv_id);
mysql_query(&mysql,sql);
memset(sql1,0,1280);
sprintf(sql1,"delete from friend where id1 = '%s' and id2 ='%s'",bag1->recv_id,bag1->send_id);
mysql_query(&mysql,sql1);
pthread_mutex_unlock(&mutex);
memset(bag1->write_buf,0,sizeof(bag1->write_buf));
strcpy(bag1->write_buf,"delete success");
}else{
memset(bag1->write_buf,0,sizeof(bag1->write_buf));
strcpy(bag1->write_buf,"no exist");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
return 0;
}
int display_fri(bag *recv_bag)
{
bag *bag1=recv_bag;
fri *list;
list=(fri *)malloc(sizeof(fri));
char sql[1280];
char sql1[1280];
MYSQL_RES *result=NULL;
MYSQL_RES *result1=NULL;
MYSQL_ROW row,row1;
int ret;
list->fri_number=0;
pthread_mutex_lock(&mutex);
memset(sql,0,1280);
sprintf(sql,"select * from friend where id1 ='%s' and relation =1",bag1->send_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
while(row=mysql_fetch_row(result))
{
list->fri_id[list->fri_number]=atoi(row[1]);
memset(sql1,0,1280);
sprintf(sql1,"select * from 身份信息 where id = '%s'",row[1]);
mysql_query(&mysql,sql1);
result1=mysql_store_result(&mysql);
row1=mysql_fetch_row(result1);
list->fri_line[list->fri_number]=atoi(row1[3]);
strcpy(list->fri_name[list->fri_number],row1[1]);
list->fri_number++;
}
pthread_mutex_unlock(&mutex);
memset(bag1->write_buf,0,sizeof(bag1->write_buf));
if(list->fri_number==0)
{
strcpy(bag1->write_buf,"no exist");
}else{
strcpy(bag1->write_buf,"success");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
send(bag1->recv_fd,list,sizeof(fri),0);
return 0;
}
int black_fri(bag *recv_bag)
{
bag *bag1;
bag1=recv_bag;
char sql[1280];
MYSQL_RES *result;
MYSQL_ROW row;
pthread_mutex_lock(&mutex);
memset(sql,0,sizeof(sql));
sprintf(sql,"select *from friend where id1 ='%s' and id2='%s' and relation =1 ",bag1->send_id,bag1->recv_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row==NULL)
{
memset(bag1->write_buf,0,sizeof(bag1->write_buf));
strcpy(bag1->write_buf,"no exist");
}else{
memset(sql,0,sizeof(sql));
sprintf(sql,"update friend set relation = -1 where id1 = '%s' and id2 ='%s' ",bag1->send_id,bag1->recv_id);
mysql_query(&mysql,sql);
memset(sql,0,sizeof(sql));
sprintf(sql,"update friend set relation = -1 where id1 = '%s' and id2 ='%s' ",bag1->recv_id,bag1->send_id);
mysql_query(&mysql,sql);
strcpy(bag1->write_buf,"success");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
pthread_mutex_unlock(&mutex);
return 0;
}
int white_fri(bag *recv_bag)
{
bag *bag1;
bag1=recv_bag;
char sql[1280];
MYSQL_RES *result;
MYSQL_ROW row;
pthread_mutex_lock(&mutex);
memset(sql,0,sizeof(sql));
sprintf(sql,"select *from friend where id1 ='%s' and id2='%s' and relation = -1 ",bag1->send_id,bag1->recv_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row==NULL)
{
memset(bag1->write_buf,0,sizeof(bag1->write_buf));
strcpy(bag1->write_buf,"failed");
}else{
memset(sql,0,sizeof(sql));
sprintf(sql,"update friend set relation = 1 where id1 = '%s' and id2 ='%s' ",bag1->send_id,bag1->recv_id);
mysql_query(&mysql,sql);
memset(sql,0,sizeof(sql));
sprintf(sql,"update friend set relation = 1 where id1 = '%s' and id2 ='%s' ",bag1->recv_id,bag1->send_id);
mysql_query(&mysql,sql);
strcpy(bag1->write_buf,"success");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
pthread_mutex_unlock(&mutex);
return 0;
}
int chat_single(bag *recv_bag)
{
bag *bag1;
bag1=recv_bag;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row,row1;
BOX *box;
time_t t;
char shijian[100];
memset(sql,0,1280);
sprintf(sql,"select * from 身份信息 where id = '%s' ",bag1->recv_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row==NULL)
{
strcpy(bag1->write_buf,"failed");
send(bag1->recv_fd,bag1,sizeof(bag),0);
return 0;
}else{
memset(sql,0,1280);
sprintf(sql,"select * from friend where id1 ='%s' and id2 ='%s' ",bag1->send_id,bag1->recv_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row1=mysql_fetch_row(result);
if(row1!=NULL)
{
if(atoi(row1[2])==-1)//黑名单
{
strcpy(bag1->write_buf,"black");
send(bag1->send_fd,bag1,sizeof(bag),0);
return 0;
}else{
bag1->send_fd=atoi(row[4]);
pthread_mutex_lock(&mutex);
strcpy(bag1->write_buf,"success");
send(bag1->recv_fd,bag1,sizeof(bag),0);
pthread_mutex_unlock(&mutex);
if(atoi(row[3])==1){
bag1->type=19;
send(bag1->send_fd,bag1,sizeof(bag),0);//给收消息的那端发消息
}else{
box=box_head;
while(box!=NULL)
{
if(box->recv_id==atoi(bag1->recv_id))
{
break;
}
box=box->next;
}
if(box==NULL)
{
box=(BOX *)malloc(sizeof(BOX));
box->friend_number=0;
box->recv_id=atoi(bag1->recv_id);
box->talk_number=0;
box->number=0;
box->file_number=0;
box->next=NULL;
box->send_id[box->talk_number]=atoi(bag1->send_id);
strcpy(box->read_buf[box->talk_number],bag1->read_buf);
box->talk_number++;
if(box_head==NULL)
{
box_head=box;
box_tail=box;
}else{
box_tail->next=box;
box_tail=box;
}
}else{
box->send_id[box->talk_number]=atoi(bag1->send_id);
strcpy(box->read_buf[box->talk_number],bag1->read_buf);
box->talk_number++;
}
}
memset(sql,0,sizeof(sql));
time(&t);
ctime_r(&t,shijian);
sprintf(sql,"insert into friend_mes values('%s','%s','%s','%s')",bag1->send_id,bag1->recv_id,bag1->read_buf,shijian);
mysql_query(&mysql,sql);
}
}else{
strcpy(bag1->write_buf,"failed");
send(bag1->send_fd,bag1,sizeof(bag),0);
return 0;
}
}
}
int mes_fri(bag * recv_bag)
{
bag * bag1=recv_bag;
fri_mes *message;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
message=(fri_mes *)malloc(sizeof(fri_mes));
message->buf_num=0;
memset(sql,0,sizeof(sql));
sprintf(sql,"select *from friend_mes where ( id1 ='%s' and id2 ='%s') or (id1 ='%s' and id2 ='%s')",bag1->send_id,bag1->recv_id,bag1->recv_id,bag1->send_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
while(row=mysql_fetch_row(result))
{
message->id[message->buf_num]=atoi(row[0]);
message->fri_id[message->buf_num]=atoi(row[1]);
strcpy(message->buf[message->buf_num],row[2]);
strcpy(message->time[message->buf_num],row[3]);
message->buf_num++;
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
send(bag1->recv_fd,message,sizeof(fri_mes),0);
return 0;
}
int create_gro(bag *recv_bag)
{
bag *bag1=recv_bag;
int j=999;
MYSQL_RES *result=NULL;
MYSQL_ROW row,row1;
char sql[1280];
int ret;
gro *group;
group=(gro *)malloc(sizeof(gro));
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from gro");
pthread_mutex_lock(&mutex);
ret=mysql_query(&mysql,sql);
if(!ret)
{
result=mysql_store_result(&mysql);
while(row=mysql_fetch_row(result))
{
if(j<atoi(row[0]))
{
j=atoi(row[0]);
}
}
j++;
group->gro_id=j;
strcpy(bag1->write_buf,"success");
sprintf(bag1->recv_id,"%d",group->gro_id);
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from 身份信息 where id ='%s'",bag1->send_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row1=mysql_fetch_row(result);
strcpy(group->gro_name,row1[1]);
group->gro_mem_id=atoi(bag1->send_id);
memset(sql,0,sizeof(sql));
sprintf(sql,"insert into gro values (%d, %d,'%s',2) ",group->gro_id,group->gro_mem_id,group->gro_name);
mysql_query(&mysql,sql);
}else{
strcpy(bag1->write_buf,"failed");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
pthread_mutex_unlock(&mutex);
return 0;
}
int dis_gro(bag *recv_bag)
{
bag * bag1=recv_bag;
char sql[1280];
int ret;
MYSQL_RES *result=NULL;
MYSQL_ROW row;
memset(sql,0,sizeof(sql));
pthread_mutex_lock(&mutex);
sprintf(sql,"select *from gro where gro_id = %d and gro_member_id = %d ",atoi(bag1->read_buf),atoi(bag1->send_id));
ret=mysql_query(&mysql,sql);
if(!ret){
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row==NULL)
{
strcpy(bag1->write_buf,"failed");
}else{
if(atoi(row[3])==2)
{
strcpy(bag1->write_buf,"success");
memset(sql,0,sizeof(sql));
sprintf(sql,"delete from gro where gro_id = %d ",atoi(bag1->read_buf));
mysql_query(&mysql,sql);
}else{
strcpy(bag1->write_buf,"no rights");
}
}
}else{
strcpy(bag1->write_buf,"failed");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
pthread_mutex_unlock(&mutex);
return 0;
}
int add_gro(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
char sql1[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row,row1,row2;
int ret;
BOX *box;
box=(BOX *)malloc(sizeof(BOX));
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from gro where gro_id ='%d'", atoi(bag1->read_buf));
ret=mysql_query(&mysql,sql);
if(!ret){
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row!=NULL)
{
pthread_mutex_lock(&mutex);
memset(sql,0,sizeof(sql));
sprintf(sql,"select *from gro where gro_id = %d and gro_member_id = %d",atoi(bag1->read_buf),atoi(bag1->send_id));
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row2=mysql_fetch_row(result);
if(row2!=NULL){
strcpy(bag1->write_buf,"sended");
pthread_mutex_unlock(&mutex);
}else{
memset(sql,0,sizeof(sql));
sprintf(sql,"select *from 身份信息 where id = '%s'",bag1->send_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row1=mysql_fetch_row(result);
strcpy(bag1->send_name,row1[1]);
memset(sql,0,sizeof(sql));
sprintf(sql,"insert into gro values(%d,%d,'%s',0)",atoi(bag1->read_buf),atoi(bag1->send_id),bag1->send_name);
mysql_query(&mysql,sql);
strcpy(bag1->write_buf,"sending");
pthread_mutex_unlock(&mutex);
}
}else{
strcpy(bag1->write_buf,"failed");
}
}else{
strcpy(bag1->write_buf,"failed");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
return 0;
}
int exit_gro(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
int ret;
memset(sql,0,sizeof(sql));
sprintf(sql,"select *from gro where gro_id = %d and gro_member_id= %d ",atoi(bag1->read_buf),atoi(bag1->send_id));
ret=mysql_query(&mysql,sql);
if(!ret)
{
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row!=NULL)
{
if(atoi(row[3])!=2){
memset(sql,0,sizeof(sql));
sprintf(sql,"delete from gro where gro_id = %d and gro_member_id= %d",atoi(bag1->read_buf),atoi(bag1->send_id));
mysql_query(&mysql,sql);
}else{
memset(sql,0,sizeof(sql));
sprintf(sql,"delete from gro where gro_id = %d",atoi(bag1->read_buf));
mysql_query(&mysql,sql);
}
strcpy(bag1->write_buf,"success");
}else{
strcpy(bag1->write_buf,"no find");
}
}else{
strcpy(bag1->write_buf,"failed");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
return 0;
}
int check_mes(bag *recv_bag)
{
bag *bag1=recv_bag;
gro_mes *message;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
message=(gro_mes *)malloc(sizeof(gro_mes));
message->number=0;
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from gro_mes where gro_id =%d",atoi(bag1->read_buf));
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
while(row=mysql_fetch_row(result))
{
message->gro_id=atoi(bag1->read_buf);
strcpy(message->buf[message->number],row[2]);
message->id[message->number]=atoi(row[1]);
strcpy(message->time[message->number],row[3]);
message->number++;
}
send(recv_bag->recv_fd,bag1,sizeof(bag),0);
send(recv_bag->recv_fd,message,sizeof(gro_mes),0);
return 0;
}
int deal_gro(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
int ret;
MYSQL_RES *result=NULL;
MYSQL_ROW row,row1;
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from gro where gro_id = %d and chmod =2 ",atoi(bag1->read_buf));//找群主
ret=mysql_query(&mysql,sql);
if(!ret)
{
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row!=NULL)
{
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from gro where gro_id =%d and gro_member_id =%d",atoi(bag1->read_buf),atoi(bag1->recv_id));//找人
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row1=mysql_fetch_row(result);
if(row1!=NULL){
if(strcmp(row[1],bag1->send_id)==0){
switch(bag1->type1)
{
case 1:
{
if(atoi(row1[3])==1)
{
strcpy(bag1->write_buf,"dealed");
}else{
memset(sql,0,sizeof(sql));
sprintf(sql,"update gro set chmod=1 where gro_id=%d and gro_member_id =%d",atoi(bag1->read_buf),atoi(bag1->recv_id));
mysql_query(&mysql,sql);
strcpy(bag1->write_buf,"success");
}
break;
}
case 2:
{
if(atoi(row1[3])==1)
{
memset(sql,0,sizeof(sql));
sprintf(sql,"update gro set chmod=0 where gro_id=%d and gro_member_id =%d",atoi(bag1->read_buf),atoi(bag1->recv_id));
mysql_query(&mysql,sql);
strcpy(bag1->write_buf,"success");
}else{
strcpy(bag1->write_buf,"no admin");
}
break;
}
case 3:
{
if(atoi(row1[3])!=2)
{
memset(sql,0,sizeof(sql));
sprintf(sql,"delete from gro where gro_id =%d and gro_member_id =%d ",atoi(bag1->read_buf),atoi(bag1->recv_id));
mysql_query(&mysql,sql);
strcpy(bag1->write_buf,"success");
}else{
strcpy(bag1->write_buf,"no possible");
}
break;
}
}
}else{
strcpy(bag1->write_buf,"no chmod");
}
}else{
strcpy(bag1->write_buf,"no find id");
}
}else{
strcpy(bag1->write_buf,"no find gro");
}
}else{
strcpy(bag1->write_buf,"failed");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
return 0;
}
int chat_double(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
char sql1[1280];
int ret;
MYSQL_RES *result=NULL;
MYSQL_RES *result1=NULL;
MYSQL_ROW row,row1,row2;
BOX *box;
char shijian[100];
time_t t;
box=box_head;
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from gro where gro_id = %d and gro_member_id = %d",atoi(bag1->read_buf),atoi(bag1->send_id));
ret=mysql_query(&mysql,sql);
if(!ret)
{
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row!=NULL)
{
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from gro where gro_id = %d",atoi(bag1->read_buf));
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
while(row1=mysql_fetch_row(result))
{
if(strcmp(row1[1],bag1->send_id)==0){
continue;
}
strcpy(bag1->recv_id,row1[1]);
memset(sql1,0,sizeof(sql));
sprintf(sql1,"select *from 身份信息 where id = '%s'",bag1->recv_id);
mysql_query(&mysql,sql1);
result1=mysql_store_result(&mysql);
row2=mysql_fetch_row(result1);
strcpy(bag1->buf,"success");
bag1->send_fd=atoi(row2[4]);
send(bag1->recv_fd,bag1,sizeof(bag),0);
if(atoi(row2[3])==1)//在线
{
bag1->type=20;
send(bag1->send_fd,bag1,sizeof(bag),0);
}else{
while(box!=NULL)
{
if(box->recv_id==atoi(bag1->recv_id))
{
break;
}
box=box->next;
}
if(box==NULL)
{
box=(BOX *)malloc(sizeof(BOX));
box->recv_id=atoi(bag1->recv_id);
box->friend_number=0;
box->number=0;
box->talk_number=0;
box->file_number=0;
box->next=NULL;
box->send_id1[box->number]=atoi(bag1->send_id);
box->group_id[box->number]=atoi(bag1->read_buf);
strcpy(box->message[box->number],bag1->write_buf);
box->number++;
if(box_head==NULL)
{
box_head=box;
box_tail=box;
}else{
box_tail->next=box;
box_tail=box;
}
}else{
box->send_id1[box->number]=atoi(bag1->send_id);
box->group_id[box->number]=atoi(bag1->read_buf);
strcpy(box->message[box->number],bag1->write_buf);
box->number++;
}
}
}
memset(sql,0,sizeof(sql));
time(&t);
ctime_r(&t,shijian);
sprintf(sql,"insert into gro_mes values(%d,%d,'%s','%s')",atoi(bag1->read_buf),atoi(bag1->send_id),bag1->write_buf,shijian);
mysql_query(&mysql,sql);
}else{
strcpy(bag1->buf,"no find");
send(bag1->recv_fd,bag1,sizeof(bag),0);
}
}else{
strcpy(bag1->buf,"failed");
send(bag1->recv_fd,bag1,sizeof(bag),0);
}
return 0;
}
int send_file(bag *recv_bag)
{
bag *bag1=recv_bag;
int fd=open("file", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IXUSR);
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
int ret;
int len;
if(strcmp(bag1->buf,"ok")==0)
{
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from 身份信息 where id= '%s'",bag1->recv_id);
ret=mysql_query(&mysql,sql);
if(!ret){
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row!=NULL){
if(atoi(row[3])==0)
{
memset(bag1->buf,0,sizeof(bag1->buf));
strcpy(bag1->buf,"no online");
send(bag1->recv_fd,bag1,sizeof(bag),0);
}else{
memset(bag1->buf,0,sizeof(bag1->buf));
strcpy(bag1->buf,"success");
send(bag1->recv_fd,bag1,sizeof(bag),0);
bag1->send_fd=atoi(row[4]);
bag1->type=22;
send(bag1->send_fd,bag1,sizeof(bag),0);
}
}else{
memset(bag1->buf,0,sizeof(bag1->buf));
strcpy(bag1->buf,"no find");
send(bag1->recv_fd,bag1,sizeof(bag),0);
}
}
}else{
write(fd,bag1->write_buf,bag1->size);
close(fd);
send(bag1->recv_fd,bag1,sizeof(bag),0);
}
return 0;
}
int recv_file(bag *recv_bag)
{
bag *bag1=recv_bag;
int fd=open("file",O_RDONLY);
int len;
memset(bag1->write_buf,0,sizeof(bag1->write_buf));
memset(bag1->buf,0,sizeof(bag1->buf));
lseek(fd,(-1)*bag1->t,SEEK_END);
while((len=read(fd,bag1->write_buf,1023))>0)
{
bag1->size=len;
send(bag1->recv_fd,bag1,sizeof(bag),0);
}
close(fd);
return 0;
}
int check_fri_fro(bag * recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
int ret;
fri *list;
list=(fri *)malloc(sizeof(fri));
list->fri_number=0;
memset(sql,0,sizeof(sql));
sprintf(sql,"select* from gro where gro_id= %d order by chmod desc",atoi(bag1->read_buf));
ret=mysql_query(&mysql,sql);
if(!ret)
{
result=mysql_store_result(&mysql);
while(row=mysql_fetch_row(result))
{
list->fri_id[list->fri_number]=atoi(row[1]);
strcpy(list->fri_name[list->fri_number],row[2]);
list->fri_line[list->fri_number]=atoi(row[3]);
list->fri_number++;
}
strcpy(bag1->write_buf,"success");
}else{
strcpy(bag1->write_buf,"failed");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
send(bag1->recv_fd,list,sizeof(fri),0);
return 0;
}
int check_info(bag *recv_bag)
{
bag *bag1=recv_bag;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from 身份信息 where id =%s",bag1->send_id);
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
row=mysql_fetch_row(result);
if(row==NULL)
{
strcpy(bag1->write_buf,"failed");
}else{
strcpy(bag1->write_buf,"success");
strcpy(bag1->send_name,row[1]);
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
return 0;
}
int check_group(bag *recv_bag)
{
bag *bag1=recv_bag;
group *lis;
char sql[1280];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
lis=(group *)malloc(sizeof(group));
lis->number=0;
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from gro where gro_member_id =%d order by chmod desc",atoi(bag1->send_id));
mysql_query(&mysql,sql);
result=mysql_store_result(&mysql);
while(row=mysql_fetch_row(result))
{
lis->id[lis->number]=atoi(row[0]);
lis->chmod[lis->number]=atoi(row[3]);
lis->number++;
}
if(lis->number!=0){
strcpy(bag1->write_buf,"success");
}else{
strcpy(bag1->write_buf,"failed");
}
send(bag1->recv_fd,bag1,sizeof(bag),0);
send(bag1->recv_fd,lis,sizeof(group),0);
return 0;
}
void *func(void *bag1)
{
pthread_detach(pthread_self());
BOX *box=box_head;
bag *recv_bag;
recv_bag=(bag *)bag1;
int t;
int ret;
switch(recv_bag->type)
{
case 1://登陆
{
t=login(recv_bag);
if(t==1)
{
while(box!=NULL)
{
if(box->recv_id==atoi(recv_bag->send_id)){
break;
}
box=box->next;
}
if(box!=NULL)
{
send(recv_bag->recv_fd,box,sizeof(BOX),0);
box->friend_number=0;
box->talk_number=0;
}else{
box=(BOX *)malloc(sizeof(BOX));
box->recv_id=atoi(recv_bag->send_id);
box->friend_number=box->talk_number=0;
box->number=0;
box->next=NULL;
if(box_head==NULL)
{
box_head=box;
box_tail=box;
}else{
box_tail->next=box;
box_tail=box;
}
send(recv_bag->recv_fd,box,sizeof(BOX),0);
}
}
break;
}
case 2://注册
{
resign(recv_bag);
break;
}
case 3://私聊
{
chat_single(recv_bag);
break;
}
case 4://加好友
{
add_fri(recv_bag);
break;
}
case 5://删好友
{
del_fri(recv_bag);
break;
}
case 6://显示好友
{
display_fri(recv_bag);
break;
}
case 7://聊天记录
{
mes_fri(recv_bag);
break;
}
case 8://拉黑好友
{
black_fri(recv_bag);
break;
}
case 9://移出好友
{
white_fri(recv_bag);
break;
}
case 10://开始群聊
{
chat_double(recv_bag);
break;
}
case 11://创建群聊
{
create_gro(recv_bag);
break;
}
case 12://解散群聊
{
dis_gro(recv_bag);
break;
}
case 13://申请加群
{
add_gro(recv_bag);
break;
}
case 14://退出群聊
{
exit_gro(recv_bag);
break;
}
case 15://查看群聊天记录
{
check_mes(recv_bag);
break;
}
case 16://管理群事务
{
deal_gro(recv_bag);
break;
}
case 17://修改信息
{
xiugai(recv_bag);
break;
}
case 18://处理消息
{
deal(recv_bag);
break;
}
case 21://传送文件
{
send_file(recv_bag);
break;
}
case 23://接收文件
{
recv_file(recv_bag);
break;
}
case 24://查看群好友
{
check_fri_fro(recv_bag);
break;
}
case 25://查看个人信息
{
check_info(recv_bag);
break;
}
case 26://查看群好友
{
check_group(recv_bag);
break;
}
}
}
void service(int sock_fd)
{
printf("服务器启动...\n");
bag recv_bag;
bag *bag1;
struct sockaddr_in client_addr;
socklen_t len;
struct epoll_event epfd;
struct epoll_event ev[20];
char choice[2];
int conn_fd;
int epollfd;
int maxevents;
int ready;
int i;
int ret;
char sql[128];
MYSQL_RES *result=NULL;
MYSQL_ROW row;
len=sizeof(struct sockaddr_in);
epollfd=epoll_create(1024);
epfd.data.fd=sock_fd;
epfd.events=EPOLLIN | EPOLLET;//读 et
if((epoll_ctl(epollfd, EPOLL_CTL_ADD, sock_fd, &epfd))<0)
{
perror("epoll_ctl failed");
return ;
}
maxevents=1;
while(1)
{
if(maxevents==0)
{
maxevents++;
}
if((ready=epoll_wait(epollfd,ev,maxevents,-1))<=0)
{
perror("epoll_wait failed");
continue;
}
for(i=0;i<ready;i++)
{
if(ev[i].data.fd==sock_fd)
{
if((conn_fd = accept(sock_fd, (struct sockaddr*)&client_addr, &len))<0)
{
perror("accept failed");
continue;
}
printf("连接成功,套接字为%d\n",conn_fd);
epfd.data.fd=conn_fd;
epfd.events=EPOLLIN | EPOLLET;
if((epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_fd, &epfd))<0)
{
perror("epoll_ctl failed");
continue;
}
maxevents++;
continue;
}else if(ev[i].events & EPOLLIN)
{
memset(&recv_bag,0,sizeof(bag));
//printf("流程%d\n",ev[i].data.fd);
ret=recv(ev[i].data.fd,&recv_bag,sizeof(bag),MSG_WAITALL);
if(ret<0)
{
close(ev[i].data.fd);
perror("recv failed");
continue;
}
if(recv_bag.type==0)
{
send(ev[i].data.fd,&recv_bag,sizeof(bag),0);
memset(sql,0,128);
sprintf(sql,"update 身份信息 set line = 0 , sockfd = 0 where line =1 and id ='%s' ",recv_bag.send_id);
mysql_query(&mysql,sql);
epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_fd, &epfd);
maxevents--;
continue;
}
pthread_t tid;
recv_bag.recv_fd=ev[i].data.fd;
bag1 = (bag*)malloc(sizeof(bag));
memcpy(bag1, &recv_bag, sizeof(bag));
pthread_create(&tid,NULL,func,(void *)bag1);
}
}
}
}
void close_mysql()
{
mysql_close(&mysql);
mysql_library_end();
}
int main()
{
int sock_fd=sock_init();
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
mysql_init1();
service(sock_fd);
close_mysql();
}
编译命令
$ gcc -I/usr/include/mysql server.c -L/usr/lib/mysql -lmysqlclient -ldl -lpthread -o server
$./server
客户端
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<stdlib.h>
#include"my_chat.h"
#include <termios.h>
#include <sys/stat.h>
#include <fcntl.h>
bag *recv_bag;
bag *send_bag;
int sing;
BOX *box;
pthread_t tid;
fri *list;
fri_mes *mes;
gro_mes *message;
group *lis;
int socket_init(struct sockaddr_in client_addr)
{
int sock_fd=socket(AF_INET,SOCK_STREAM,0);
client_addr.sin_addr.s_addr=htonl(INADDR_ANY);//通信对象的IP地址,0.0.0.0表示所有IP地址
//client_addr.sin_addr.s_addr=inet_addr("192.168.30.155");
client_addr.sin_family=AF_INET; //IPv4协议
client_addr.sin_port=htons(SERV_PORT);//应用层端口号
//绑定套接字和结构体----主机自检端口号是否重复,IP是否准确
if(connect(sock_fd,(struct sockaddr *)&client_addr,sizeof(client_addr))<0)
{
perror("connect failed");
return -1;
}else{
printf("客户端初始化完成\n");
}
return sock_fd;
}
void getpasswd(char *passwd)
{
struct termios oldt, newt;
char ch;
tcgetattr(0, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
int i = 0;
while(1)
{
tcsetattr(0, TCSANOW, &newt);
ch = getchar();
tcsetattr(0, TCSANOW, &oldt);
if(ch=='\n')
{
passwd[i]='\0';
break;
}
passwd[i]=ch;
i++;
printf("*");
}
printf("\n");
}
int login(int fd)
{
int ret;
printf("--------------------------------------------\n");
printf(" 请输入账号:\n");
scanf("%s",send_bag->send_id);
getchar();
printf(" 请输入密码:\n");
getpasswd(send_bag->read_buf);
memset(send_bag->write_buf,0,1024);
ret=send(fd,send_bag,sizeof(bag),0);//发帐号密码
if(ret<0)
{
perror("send failed");
exit(1);
}
pthread_mutex_lock(&mutex_cli);
while(sing==0){
pthread_cond_wait(&cond_cli, &mutex_cli);
}
pthread_mutex_unlock(&mutex_cli);
sing=0;
}
int resign(int fd)
{
int ret;
char passwd[8];
memset(passwd,0,8);
printf("--------------------------------------------\n");
printf(" 请输入昵称:\n");
scanf("%s",send_bag->send_name);
getchar();
printf(" 请输入密码:\n");
getpasswd(send_bag->read_buf);
printf(" 请再输入一次密码:\n");
getpasswd(passwd);
while(1){
if(strcmp(send_bag->read_buf,passwd)==0)
{
printf(" 两次输入一致!\n");
ret=send(fd,send_bag,sizeof(bag),0);//发送帐号密码
if(ret<0)
{
perror("send failed");
exit(1);
}
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
printf(" 注册成功!你的账号是%s\n",send_bag->send_id);
printf(" 请重新登陆!\n");
break;
}else{
printf(" 输入不正确!请再次输入!\n");
printf(" 请输入:\n");
getpasswd(passwd);
continue;
}
}
}
int add_fri(int fd)
{
int t;
printf(" 输入要添加的账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
t=atoi(send_bag->write_buf);
if(t==1)
{
printf(" 该人已经是你的好友!\n");
}else if(t==-2)
{
printf(" 该账号不存在!\n");
}else if(t==-1)
{
printf(" 该人已被你拖入黑名单!\n");
}else if(t==0)
{
printf(" 已发送请求!\n");
}else if(t==3){
printf(" 已发送过申请!\n");
}else{
printf(" 添加错误!\n");
}
return 0;
}
int xiugai(int fd)
{
int choice;
printf("--------------------------------------------\n");
printf(" 1--修改昵称\n");
printf(" 2--修改密码\n");
printf(" 0--退出\n");
printf("--------------------------------------------\n");
printf(" 请选择\n");
scanf("%d",&choice);
getchar();
switch(choice)
{
case 1:
{
send_bag->type1=1;
printf(" 输入修改的名字:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
printf("修改完成!\n");
break;
}
case 2:
{
send_bag->type1=2;
printf(" 输入修改的密码:\n");
getpasswd(send_bag->read_buf);
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
printf("修改完成!\n");
break;
}
case 0:
return 0;
default:
printf(" 输入错误!返回!\n");
return 0;
}
}
void menu1()
{
printf("--------------------------------------------\n");
printf(" 菜单\n");
printf("--------------------------------------------\n");
printf(" 1--开始私聊\n");
printf(" 2--添加好友\n");
printf(" 3--删除好友\n");
printf(" 4--显示好友列表\n");
printf(" 5--查看好友聊天记录\n");
printf(" 6--好友拖入黑名单\n");
printf(" 7--好友移出黑名单\n");
printf(" 8--开始群聊\n");
printf(" 9--创建群聊\n");
printf(" 10--解散群聊\n");
printf(" 11--申请加群\n");
printf(" 12--退出群聊\n");
printf(" 13--查看群聊天记录\n");
printf(" 14--管理群聊\n");
printf(" 15--修改个人信息\n");
printf(" 16--处理消息\n");
printf(" 17--文件传送\n");
printf(" 18--文件接收\n");
printf(" 19--查看群好友列表\n");
printf(" 20--查看个人信息\n");
printf(" 21--查看群列表\n");
printf(" 0--退出\n");
printf("--------------------------------------------\n");
printf(" 请选择:\n");
}
void menu()
{
printf("--------------------------------------------\n");
printf("-----------------登录界面--------------------\n");
printf("--------------------------------------------\n");
printf(" 1--登陆\n");
printf(" 2--注册\n");
printf(" 0--退出\n");
printf("--------------------------------------------\n");
printf("--------------------------------------------\n");
printf(" 请选择:\n");
}
int deal(int fd)
{
int choose;
int i;
int choice;
printf("--------------------------------------------\n");
printf(" 1--处理好友申请\n");
printf(" 2--查看好友消息\n");
printf(" 3--查看群消息\n");
printf(" 4--退出\n");
printf("--------------------------------------------\n");
printf(" 请选择:\n");
scanf("%d",&choose);
getchar();
switch(choose)
{
case 1:
{
send_bag->type1=1;
if(box->friend_number==0)
{
printf("暂无好友申请!\n");
getchar();
break;
}else{
for(i=0;i<box->friend_number;i++)
{
printf(" 账号为%d请求加你为好友!\n",box->plz_id[i]);
printf(" 1--同意\n");
printf(" 2--拒绝\n");
printf("--------------------------------------------\n");
printf(" 请选择:\n");
scanf("%d",&choice);
getchar();
if(choice==1)
{
strcpy(send_bag->read_buf,"tongyi");
sprintf(send_bag->recv_id,"%d",box->plz_id[i]);
send(fd,send_bag,sizeof(bag),0);
}else if(choice ==2)
{
strcpy(send_bag->read_buf,"jujue");
sprintf(send_bag->recv_id,"%d",box->plz_id[i]);
send(fd,send_bag,sizeof(bag),0);
}else{
printf(" 输入错误!\n");
break;
}
}
box->friend_number=0;
printf(" 处理完成!\n");
memset(send_bag->read_buf,0,1024);
break;
}
}
case 2:
{
send_bag->type1=2;
if(box->talk_number==0)
{
printf("暂无好友消息!\n");
getchar();
break;
}else{
for(i=0;i<box->talk_number;i++)
{
printf("账号%d:%s\n", box->send_id[i], box->read_buf[i]);
}
box->talk_number=0;
printf("处理完成!\n");
break;
}
}
case 3:
{
send_bag->type1=3;
if(box->number==0)
{
printf("暂无群聊消息!\n");
getchar();
break;
}else{
for(i=0;i<box->number;i++)
{
printf("群号为%d 账号%d:%s\n", box->group_id[i],box->send_id1[i], box->message[i]);
}
box->number=0;
printf("处理完成!\n");
break;
}
}
case 4:
break;
default:
{
printf("输入错误!\n");
printf("按任意键返回!\n");
getchar();
break;
}
}
}
int del_fri(int fd)
{
printf("--------------------------------------------\n");
printf(" 输入要删除的好友账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"delete success")==0)
{
printf(" 删除成功!\n");
}else
{
printf(" 删除失败!\n");
}
return 0;
}
int display_fri(int fd)
{
int i;
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("好友列表:\n");
for(i=0;i<list->fri_number;i++)
{
printf("id:%d name:%s",list->fri_id[i],list->fri_name[i]);
if(list->fri_line[i]==1)
{
printf(" --在线\n");
}else if(list->fri_line[i]==0)
{
printf(" --掉线\n");
}
}
}else{
printf("你没有好友!\n");
}
return 0;
}
int chat_single(int fd)
{
printf("--------------------------------------------\n");
printf(" 输入聊天的人的账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
printf("与%s开始聊天!\n",send_bag->recv_id);
while(1)
{
scanf("%[^\n]",send_bag->read_buf);
getchar();
if(strcmp(send_bag->read_buf,"#obey")==0)
{
printf("与%s聊天结束!\n",send_bag->recv_id);
break;
}
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"black")==0)
{
printf("你处于黑名单中!无法发送消息!\n");
break;
}else if(strcmp(send_bag->write_buf,"failed")==0)
{
printf("聊天失败!可能不是好友!或者暂无该账号!\n");
break;
}
}
memset(send_bag->recv_id,0,sizeof(send_bag->recv_id));
return 0;
}
int black_fri(int fd)
{
printf("--------------------------------------------\n");
printf(" 输入拉黑的人的账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("拉黑成功!\n");
}else{
printf("拉黑失败!\n");
}
return 0;
}
int check_fri(int fd)
{
int i;
printf("--------------------------------------------\n");
printf(" 查看聊天记录的好友账号(上限五百条):\n");
scanf("%s",send_bag->recv_id);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
for(i=0;i<mes->buf_num;i++)
{
if(mes->id[i]==atoi(send_bag->send_id))
printf("\033[34mtime:%s id:%d message;%s\n\033[0m",mes->time[i],mes->id[i],mes->buf[i]);
else
printf("\033[32mtime:%s id:%d message;%s\n\033[0m",mes->time[i],mes->id[i],mes->buf[i]);
}
}
int white_fri(int fd)
{
printf("--------------------------------------------\n");
printf(" 输入移出的人的账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("移出成功!\n");
}else{
printf("移出失败!\n");
}
return 0;
}
int create_gro(int fd)
{
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("创建成功!创建的群号为%s!\n",send_bag->recv_id);
}else{
printf("创建失败!\n");
}
return 0;
}
int dis_gro(int fd)
{
printf("--------------------------------------------\n");
printf(" 输入解散的群聊的账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("解散成功!\n");
}else if(strcmp(send_bag->write_buf,"no rights")==0)
{
printf("您没有权限!\n");
}else {
printf("解散失败!\n");
}
return 0;
}
int add_gro(int fd)
{
printf("--------------------------------------------\n");
printf(" 输入申请加入的群聊的账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"sending")==0)
{
printf("成功加入群聊!\n");
}else if(strcmp(send_bag->write_buf,"sended")==0)
{
printf("已经进入群聊!\n");
}else{
printf("进群失败!\n");
}
return 0;
}
int exit_gro(int fd)
{
printf("--------------------------------------------\n");
printf(" 输入要退出的群聊的账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("退出成功!\n");
}else if(strcmp(send_bag->write_buf,"no find")==0)
{
printf("您不在该群中!\n");
}else{
printf("退出出错!\n");
}
return 0;
}
int check_gro(int fd)
{
int i;
printf("--------------------------------------------\n");
printf(" 输入要查看聊天记录的群聊的账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
for(i=0;i<message->number;i++)
{
if(message->id[i]==atoi(send_bag->send_id))
printf("\033[34mtime:%s id:%d message;%s\n\033[0m",message->time[i],message->id[i],message->buf[i]);
else
printf("\033[32mtime:%s id:%d message;%s\n\033[0m",message->time[i],message->id[i],message->buf[i]);
}
return 0;
}
int chat_double(int fd)
{
printf("--------------------------------------------\n");
printf(" 输入聊天的群聊的账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
printf("欢迎进入%s群聊!\n",send_bag->read_buf);
while(1)
{
scanf("%[^\n]",send_bag->write_buf);
getchar();
if(strcmp(send_bag->write_buf,"#obey")==0)
{
printf("退出%s群聊!\n",send_bag->read_buf);
break;
}
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->buf,"no find")==0)
{
printf("你未加入该群聊!\n");
break;
}
if(strcmp(send_bag->buf,"failed")==0)
{
printf("进入失败!\n");
break;
}
}
memset(send_bag->read_buf,0,sizeof(send_bag->read_buf));
return 0;
}
int deal_gro(int fd)
{
int choose;
printf("--------------------------------------------\n");
printf(" 1--设置管理员:\n");
printf(" 2--取消管理员\n");
printf(" 3--群踢人\n");
printf(" 4--返回\n");
scanf("%d",&choose);
getchar();
switch(choose)
{
case 1:
{
send_bag->type1=1;
printf("请输入要设置的管理员账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
printf("请输入设置群聊的账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 2:
{
send_bag->type1=2;
printf("请输入要取消管理的管理员账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
printf("请输入设置群聊的账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 3:
{
send_bag->type1=3;
printf("请输入被踢出人的账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
printf("请输入设置群聊的账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli, &mutex_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 4:
{
printf("返回上一级!\n");
return 0;
}
default:
{
printf("输入错误!按任意键返回!");
getchar();
return 0;
}
}
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("成功修改!\n");
}else if(strcmp(send_bag->write_buf,"dealed")==0)
{
printf("已经是管理员了!\n");
}else if(strcmp(send_bag->write_buf,"no admin")==0)
{
printf("该用户还不是管理员!\n");
}else if(strcmp(send_bag->write_buf,"no possible")==0)
{
printf("该人是群主!\n");
}else if(strcmp(send_bag->write_buf,"no chmod")==0)
{
printf("没有权限!\n");
}else if(strcmp(send_bag->write_buf,"no find id")==0)
{
printf("该人不在该群!\n");
}else if(strcmp(send_bag->write_buf,"no find gro")==0)
{
printf("该群不存在!\n");
}else{
printf("修改失败!\n");
}
return 0;
}
int send_file(int fd)
{
struct stat buf;
int pd;
int i,j;
char name[100];
int len;
j=0;
printf("要发送好友的账号:\n");
scanf("%s",send_bag->recv_id);
getchar();
printf("要发送的文件:(绝对路径)\n");
scanf("%s",send_bag->read_buf);
getchar();
if((lstat(send_bag->read_buf,&buf))<0)
{
printf("获取文件失败!按任意键返回!\n");
getchar();
return 0;
}
if((pd=open(send_bag->read_buf,O_RDONLY))<0)
{
printf("无法打开文件!按任意键返回!\n");
getchar();
return 0;
}
sing=0;
send_bag->cont=0;
memset(send_bag->buf,0,sizeof(send_bag->buf));
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
for(i=0;i<=strlen(send_bag->read_buf);i++)
{
if(send_bag->read_buf[i]=='/')
{
j=0;
i++;
memset(name,0,sizeof(name));
}
name[j]=send_bag->read_buf[i];
j++;
}
name[i]='\0';
strcpy(send_bag->read_buf,name);
send_bag->t=buf.st_size;
while((len=read(pd,send_bag->write_buf,1023))>0)//1023
{
send_bag->size=len;
send(fd,send_bag,sizeof(bag),0);
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
printf("cont=%d\n",send_bag->cont);
pthread_mutex_lock(&mutex_cli);
while(sing==0){
pthread_cond_wait(&cond_cli, &mutex_cli);
}
pthread_mutex_unlock(&mutex_cli);
send_bag->cont++;
sing=0;
}
close(pd);
sing=0;
strcpy(send_bag->buf,"ok");
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
while(sing==0){
pthread_cond_wait(&cond_cli, &mutex_cli);
}
pthread_mutex_unlock(&mutex_cli);
sing=0;
if(strcmp(send_bag->buf,"success")==0)
{
printf("传送完成!\n");
}else if(strcmp(send_bag->buf,"no online")==0)
{
printf("该账号不在线!\n");
}else if(strcmp(send_bag->buf,"no find")==0)
{
printf("该账号不存在!\n");
}else{
printf("%s",send_bag->buf);
printf("发送错误!\n");
}
return 0;
}
int recv_file(int fd)
{
int i;
int choice;
send_bag->cont=0;
if(box->file_number==0)
{
printf("暂无文件需要接收!按任意键退出!\n");
getchar();
return 0;
}else{
for(i=0;i<box->file_number;i++)
{
printf(" %d给你发送了一个文件%s,是否接收!\n",box->file_id[i],box->file_name[i]);
printf(" 1--同意\n");
printf(" 2--拒绝\n");
printf("--------------------------------------------\n");
printf(" 请选择:\n");
scanf("%d",&choice);
getchar();
if(choice==1)
{
memset(send_bag->buf,0,sizeof(send_bag->buf));
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
while(sing==0){
pthread_cond_wait(&cond_cli, &mutex_cli);
}
pthread_mutex_unlock(&mutex_cli);
sing=0;
printf("接收完成!\n");
}else if(choice ==2)
{
printf("已拒绝接收!\n");
}else{
printf("输入错误!\n");
}
}
box->file_number=0;
}
return 0;
}
int check_gro_fri(int fd)
{
int i=0;
printf("要查看的群账号:\n");
scanf("%s",send_bag->read_buf);
getchar();
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli,&mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("群好友列表:\n");
for(i=0;i<list->fri_number;i++)
{
if(list->fri_line[i]==2)
{
printf("群主: id:%d name:%s\n",list->fri_id[i],list->fri_name[i]);
}else if(list->fri_line[i]){
printf("管理员: id:%d name:%s\n",list->fri_id[i],list->fri_name[i]);
}else{
printf("普通成员: id:%d name:%s\n",list->fri_id[i],list->fri_name[i]);
}
}
}else{
printf("查询失败!\n");
}
return 0;
}
int check_info(int fd)
{
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli,&mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
printf("id:%s name:%s\n",send_bag->send_id,send_bag->send_name);
}else{
printf("显示错误!\n");
}
return 0;
}
int check_group(int fd)
{
int i;
send(fd,send_bag,sizeof(bag),0);
pthread_mutex_lock(&mutex_cli);
pthread_cond_wait(&cond_cli,&mutex_cli);
pthread_mutex_unlock(&mutex_cli);
if(strcmp(send_bag->write_buf,"success")==0)
{
for(i=0;i<lis->number;i++)
{
if(lis->chmod[i]==2)
{
printf("你拥有的群: id:%d\n",lis->id[i]);
}else if(lis->chmod[i]==1)
{
printf("你管理的群: id:%d\n",lis->id[i]);
}else if(lis->chmod[i]==0)
{
printf("你加入的群: id:%d\n",lis->id[i]);
}
}
}else{
printf("暂未加入群!\n");
}
return 0;
}
void *thread_send(void *arg)
{
int fd=*(int *)arg;
int ret;
int t;
int choose;
send_bag=(bag *)malloc(sizeof(bag));
send_bag->send_fd=fd;
while(1){
menu();
scanf("%d",&choose);
getchar();
switch (choose){
case 1://登陆
{
send_bag->type=1;
login(fd);
break;
}
case 2://注册
{
send_bag->type=2;
resign(fd);
break;
}
case 0://退出
{
send_bag->type=0;
ret=send(fd,send_bag,sizeof(bag),0);
if(ret<0){
perror("send failed");
exit(1);
}
printf("即将退出!\n");
pthread_exit(0);
}
default:
{
printf("输入错误!重新输入!\n");
break;
}
}
if(choose<0||choose>2)
{
continue;
}else if(choose==1){
if(strcmp(send_bag->write_buf,"login successfully")==0)
{
printf("%s欢迎登陆~\n",send_bag->send_name);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}else if(strcmp(send_bag->write_buf,"login failed")==0)
{
printf("登陆失败!请重新登陆!\n");
printf("按任意键继续!\n");
getchar();
system("clear");
continue;
}else{
printf("对比出错!请返回!\n");
printf("按任意键继续!\n");
getchar();
system("clear");
continue;
}
}else if(choose==2){
printf("按任意键继续!\n");
getchar();
system("clear");
continue;
}
}
while(1)
{
menu1();
scanf("%d",&choose);
getchar();
switch(choose){
case 1://私聊
{
send_bag->type=3;
chat_single(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 2://加好友
{
send_bag->type=4;
add_fri(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 3://删好友
{
send_bag->type=5;
del_fri(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 4://显示好友列表
{
send_bag->type=6;
display_fri(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 5://查看聊天记录
{
send_bag->type=7;
check_fri(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 6://拉黑好友
{
send_bag->type=8;
black_fri(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 7://移出好友
{
send_bag->type=9;
white_fri(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 8://开始群聊
{
send_bag->type=10;
chat_double(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 9://创建群聊
{
send_bag->type=11;
create_gro(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 10://解散群聊
{
send_bag->type=12;
dis_gro(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 11://申请加群
{
send_bag->type=13;
add_gro(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 12://退出群聊
{
send_bag->type=14;
exit_gro(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 13://查看群聊天记录
{
send_bag->type=15;
check_gro(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 14://管理群事务
{
send_bag->type=16;
deal_gro(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 0://退出
{
send_bag->type=0;
send(fd,send_bag,sizeof(bag),0);
pthread_exit(0);
return 0;
}
case 15://修改信息
{
send_bag->type=17;
xiugai(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 16://处理消息
{
send_bag->type=18;
deal(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 17://发送文件
{
send_bag->type=21;
send_file(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 18://接收文件
{
send_bag->type=23;
recv_file(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 19://查看群好友列表
{
send_bag->type=24;
check_gro_fri(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 20://查看个人信息
{
send_bag->type=25;
check_info(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
case 21://查看群列表
{
send_bag->type=26;
check_group(fd);
printf("按任意键继续!\n");
getchar();
system("clear");
break;
}
default:
{
printf("输入错误!重新输入!\n");
printf("按任意键继续!\n");
getchar();
system("clear");
continue;
}
}
}
}
void *recv_box(void *arg)
{
int fd=*(int *)arg;
recv(fd,box,sizeof(BOX),MSG_WAITALL);
pthread_exit(0);
}
void *recv_fri(void *arg)
{
int fd=*(int *)arg;
recv(fd,list,sizeof(fri),MSG_WAITALL);
pthread_exit(0);
}
void *recv_frimes(void *arg)
{
int fd=*(int *)arg;
if(strcmp(recv_bag->send_id,send_bag->recv_id)==0)
{
printf("\033[34mid:%s %s\n\033[0m",recv_bag->send_id,recv_bag->read_buf);
}else{
printf("来了一条消息!\n");
box->send_id[box->talk_number]=atoi(recv_bag->send_id);
strcpy(box->read_buf[box->talk_number],recv_bag->read_buf);
box->talk_number++;
}
pthread_exit(0);
}
void *display_frimes(void *arg)
{
int fd=*(int *)arg;
recv(fd,mes,sizeof(fri_mes),MSG_WAITALL);
pthread_exit(0);
}
void *recv_gromes(void *arg)
{
int fd=*(int *)arg;
if(strcmp(recv_bag->write_buf,send_bag->write_buf)==0)
{
;
}else if(strcmp(recv_bag->read_buf,send_bag->read_buf)==0)
{
printf("\033[34mid:%s %s\n\033[0m",recv_bag->send_id,recv_bag->write_buf);
}else{
printf("来了一条群消息!\n");
box->send_id1[box->number]=atoi(recv_bag->send_id);
box->group_id[box->number]=atoi(recv_bag->read_buf);
strcpy(box->message[box->number],recv_bag->write_buf);
box->number++;
}
pthread_exit(0);
}
void *display_gromes(void *arg)
{
int fd=*(int *)arg;
recv(fd,message,sizeof(gro_mes),MSG_WAITALL);
pthread_exit(0);
}
void *recv_group(void *arg)
{
int fd=*(int *)arg;
recv(fd,lis,sizeof(group),MSG_WAITALL);
pthread_exit(0);
}
void *thread_recv(void *arg)
{
int ret;
int fd=*(int *)arg;
recv_bag=(bag *)malloc(sizeof(bag));
box=(BOX *)malloc(sizeof(BOX));
list=(fri *)malloc(sizeof(fri));
mes=(fri_mes *)malloc(sizeof(fri_mes));
message=(gro_mes *)malloc(sizeof(gro_mes));
lis=(group *)malloc(sizeof(group));
while(1)
{
memset(recv_bag,0,sizeof(bag));
ret=recv(fd,recv_bag,sizeof(bag),MSG_WAITALL);
if(ret<0)
{
perror("recv failed");
exit(1);
}
switch(recv_bag->type)
{
case 0://退出
{
printf("退出成功!\n");
pthread_exit(0);
return 0;
}
case 1://登陆
{
strcpy(send_bag->send_name, recv_bag->send_name);
memset(send_bag->write_buf, 0, sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf, recv_bag->write_buf);
send_bag->send_fd = recv_bag->recv_fd;
if(strcmp(send_bag->write_buf,"login successfully")==0)
{
pthread_create(&tid,NULL,recv_box,(void *)&fd);
pthread_join(tid,NULL);
printf("离线时好友信息数:%d\n",box->talk_number);
printf("离线时好友请求数:%d\n",box->friend_number);
printf("离线时群聊信息数:%d\n",box->number);
}
pthread_mutex_lock(&mutex_cli);
sing=1;
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 2://注册
{
strcpy(send_bag->send_id,recv_bag->send_id);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 3://私聊
{
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 19://在线时私聊收消息
{
pthread_create(&tid,NULL,recv_frimes,(void *)&fd);
pthread_join(tid,NULL);
break;
}
case 4://加好友
{
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 5://删好友
{
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 6://显示好友
{
memset(send_bag->write_buf, 0, sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf, recv_bag->write_buf);
memset(list,0,sizeof(fri));
pthread_create(&tid,NULL,recv_fri,(void *)&fd);
pthread_join(tid,NULL);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 7://查看聊天记录
{
pthread_create(&tid,NULL,display_frimes,(void *)&fd);
pthread_join(tid,NULL);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 8://拉黑好友
{
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 9://移出好友
{
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 10://开始群聊
{
strcpy(send_bag->buf,recv_bag->buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 20://收群聊消息
{
pthread_create(&tid,NULL,recv_gromes,(void *)&fd);
pthread_join(tid,NULL);
break;
}
case 11://创建群聊
{
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf,recv_bag->write_buf);
strcpy(send_bag->recv_id,recv_bag->recv_id);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 12://解散群聊
{
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 13://加入群聊
{
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 14://退出群聊
{
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 15://查看群聊天记录
{
pthread_create(&tid,NULL,display_gromes,(void *)&fd);
pthread_join(tid,NULL);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 16://管理群事务
{
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 17://修改
{
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 18://处理消息
{
if(recv_bag->type1==1)
{
pthread_mutex_lock(&mutex_cli);
box->plz_id[box->friend_number]=atoi(recv_bag->send_id);
box->friend_number++;
printf("有一条好友申请!\n");
pthread_mutex_unlock(&mutex_cli);
}
break;
}
case 21://传送文件
{
strcpy(send_bag->buf,recv_bag->buf);
pthread_mutex_lock(&mutex_cli);
sing=1;
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 22://收到文件
{
strcpy(send_bag->recv_id,recv_bag->send_id);
strcpy(send_bag->read_buf,recv_bag->read_buf);
send_bag->size=recv_bag->size;
send_bag->t=recv_bag->t;
printf("%s给你发送了一个文件%s,快去接收吧!\n",send_bag->recv_id,send_bag->read_buf);
box->file_id[box->file_number]=atoi(send_bag->recv_id);
strcpy(box->file_name[box->file_number],send_bag->read_buf);
box->file_number++;
pthread_mutex_lock(&mutex_cli);
sing=1;
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 23://接收文件
{
char file[100];
memset(send_bag->buf,0,sizeof(send_bag->buf));
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
strcpy(file,send_bag->read_buf);
strcpy(send_bag->write_buf,recv_bag->write_buf);
strcpy(send_bag->buf,recv_bag->buf);
send_bag->size=recv_bag->size;
int pd=open(file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IXUSR);
write(pd,send_bag->write_buf,send_bag->size);
close(pd);
pthread_mutex_lock(&mutex_cli);
sing=1;
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 24://查看群好友列表
{
memset(send_bag->write_buf, 0, sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf, recv_bag->write_buf);
memset(list,0,sizeof(fri));
pthread_create(&tid,NULL,recv_fri,(void *)&fd);
pthread_join(tid,NULL);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 25://查看个人信息
{
memset(send_bag->write_buf,0,sizeof(send_bag->write_buf));
memset(send_bag->send_name,0,sizeof(send_bag->send_name));
strcpy(send_bag->send_name,recv_bag->send_name);
strcpy(send_bag->write_buf,recv_bag->write_buf);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
case 26://查看群列表
{
memset(send_bag->write_buf, 0, sizeof(send_bag->write_buf));
strcpy(send_bag->write_buf, recv_bag->write_buf);
memset(lis,0,sizeof(group));
pthread_create(&tid,NULL,recv_group,(void *)&fd);
pthread_join(tid,NULL);
pthread_mutex_lock(&mutex_cli);
pthread_cond_signal(&cond_cli);
pthread_mutex_unlock(&mutex_cli);
break;
}
}
}
}
int main()
{
struct sockaddr_in client_addr;
int sockfd=socket_init(client_addr);
if(sockfd<0) return 0;
pthread_t tid1,tid2;
sing=0;
pthread_mutex_init(&mutex_cli,NULL);
pthread_cond_init(&cond_cli,NULL);
pthread_create(&tid1,NULL,thread_send,(void *)&sockfd);
pthread_create(&tid2,NULL,thread_recv,(void *)&sockfd);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
编译命令
$ gcc client.c -lpthread -o client
$./client
如有问题,希望可以指出。
版权声明:本文为m0_50331127原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。