聊天室源码

聊天室源码


链接: github.
需要注意的需要切换到test分支上去,主分支bug太多了。
编译时
服务器:

gcc server.c serverfun.c -o server -lpthread -lmysqlclient

客户端:

gcc c.c cfun.c -o client -lpthread

server.c

#include "mysqlc.h"
#define EVENTS_MAX_SIZE 20
#define SERV_PORT 9000
#define MAX_CONTECT_SIZE 20
people_list_t list=NULL;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
void mylogin(struct work s1,struct s1* s)
{
    struct work rets;
     int c=judege(s1.name,s1.password);
    if (c==1)
	{
    people_node_t *new=NULL;
    new=(people_node_t*)malloc(sizeof(people_node_t));
    peple a;
     new->data.id=find_byname(s1.name);
    strcpy(new->data.name,s1.name);
    new->data.fd=s->conn_fd;
    rets.sid=new->data.id;
    people_node_t *p;
    List_ForEach(list,p)
    {
        printf("id:%d name:%s fd:%d\n",p->data.id,p->data.name,p->data.fd);
            if (p->data.id==new->data.id)
            {
                close(p->data.fd);
                List_FreeNode(p);
                break;
            }
    }

     List_AddTail(list,new);
        rets.ret=1;
		printf("用户%s登陆成功\n",s1.name);
	}
	else if (c==0)
	{   rets.ret=0;
			printf("用户%s登陆失败\n",s1.name);
	}
	else printf("mysql error\n");
     send(s->conn_fd,&rets,sizeof(rets),0);
}
void mylogon(struct work s1,struct s1* s)
{
    struct work rets;
     int c=judegeon(s1.name,s1.password);
    if (c==1)
	{
        rets.ret=1;
		printf("用户%s注册成功\n",s1.name);
	}
	else if (c==0)
	{   rets.ret=0;
			printf("用户%s注册失败\n",s1.name);
	}
	else printf("mysql error\n");
     send(s->conn_fd,&rets,sizeof(rets),0);
}
void *solve(void* temp)
{
    int out;
    struct work s1;
    int num;
        struct s1 *s=(struct s1*)temp;
    struct epoll_event ev;
    ev.data.fd = s->conn_fd;
     char *filename;
       struct work sim;
    ev.events = EPOLLIN |EPOLLONESHOT;
    printf("efd:%d cfd:%d\n",s->epfd,s->conn_fd);
    int ret = recv(s->conn_fd,&s1,sizeof(struct work),0);
    if (ret==0)
    {
        people_node_t* p;
        pthread_mutex_lock(&mutex2);
        List_ForEach(list,p)
        {
            if (p->data.fd==s->conn_fd)
             {List_FreeNode(p);
            break;}
        }
         pthread_mutex_unlock(&mutex2);
        epoll_ctl(s->epfd,EPOLL_CTL_DEL,s->conn_fd,NULL);
        close(s->conn_fd);
        printf("对端已经关闭了");
        pthread_exit(0);
    }
  //  read(s->conn_fd,buf,sizeof(buf));
//    printf("%s %s",s1.name,s1.password);
    switch(s1.tye)
    {
        case 's':
        mylogin(s1,s);
        break;
        case 'b':
        mylogon(s1,s);
        break;
        case 'c':
        getmyfriend(s1.sid);
        break;
        case 'e':
        break;
        case 'd': pthread_mutex_lock(&mutex);
        printf("id:%d 是 %d\n",s1.rid,ishe(s1.rid,s));
                pthread_mutex_unlock(&mutex);
        break;
        case 'f':
        add_friends(s1);
        break;
        case 'g':
        getmyrequst(s1.sid);
        break;
        case 'h':
        printf("i get a 'h\n");
        agree(s1);
        break;
        case 'i':
        printf("i get a 'i'\n");
        disagree(s1);
        break;
        case 'j':
        delete_friend(s1);
        break;
        case 'k':
       ev.events = EPOLLIN |EPOLLONESHOT;
        epoll_ctl(s->epfd,EPOLL_CTL_MOD,s->conn_fd,&ev);
         ssend_mes(s1);
        pthread_detach(pthread_self());
        pthread_exit(0);
        return 0;
        break;
        case 'l':
         ev.events = EPOLLIN |EPOLLONESHOT;
        epoll_ctl(s->epfd,EPOLL_CTL_MOD,s->conn_fd,&ev);
          read_mes(s1);
        pthread_detach(pthread_self());
        pthread_exit(0);
        break;
        case 'm':
        printf("m\n");
        sendallmes(s1.sid);
        break;
        case 'n':
        getallnmes(s1.sid);
        break;
        case 'o':
        createg(s1);
        break;
        case 'p':
        joingroups(s1);
        break;
        case 'q':
        printf("i got q\n");
        getmygroup(s1.sid);
        break;
        case 'r':
        getmygrequst(s1.rid,s1.sid);
        break;
        case 't':
        agreeg(s1);
        break;
        case 'u':
        disagreeg(s1);
        break;
        case 'v':
        getmates(s1.sid,s->conn_fd);
        break;
        case 'w':
        setadmin(s1,s->conn_fd);
        break;
        case 'x':
        delmate(s1,s->conn_fd);
        break;
        case 'y':
        killgroup(s1.sid);
        break;
        case 'z':
          ev.events = EPOLLIN |EPOLLONESHOT;
        epoll_ctl(s->epfd,EPOLL_CTL_MOD,s->conn_fd,&ev);
        gsend_mes(s1);
        pthread_detach(pthread_self());
        pthread_exit(0);
        return 0;
        break;
        case '1':
         ev.events = EPOLLIN |EPOLLONESHOT;
        epoll_ctl(s->epfd,EPOLL_CTL_MOD,s->conn_fd,&ev);
        read_gmes(s1);
        pthread_detach(pthread_self());
        pthread_exit(0);
        return 0;
        break;
        case '2':
        getallgmes(s1.rid,s1.sid,s->conn_fd);
        break;
        case '3':
        getallngmes(s1.rid,s1.sid,s->conn_fd);
        break;
        case '4':
    //    epoll_ctl(s->epfd,EPOLL_CTL_DEL,s->conn_fd,NULL);
        sim.tye='d';
        filename=genRandomString(4);
        out=creat(filename,0664);
        int len=s1.ret;
        char buf[5000];
        while(len>0 ){
            memset(buf,'\0',sizeof(buf));
            num=recv(s->conn_fd,buf,4096,0); 
            len=len-num;
            write(out,buf,num);
        }
        
   //       epoll_ctl(s->epfd,EPOLL_CTL_ADD,s->conn_fd,&ev);
        savefile(s1,filename);
        close(out);
        send(s->conn_fd,&sim,sizeof(struct work),0);
        break;
        case '5':
        sendfilelist(s1);
        break;
        case '6':
        send_file(s1);
        break;
        case '7':
        delete_file(s1);
        break;
        default:
        printf("not really:%c\n",s1.tye);
    }
    printf("%s结束\n",s1.mes);
    epoll_ctl(s->epfd,EPOLL_CTL_MOD,s->conn_fd,&ev);
    pthread_detach(pthread_self());
    pthread_exit(0);
    return 0;
}
int main()
{
    signal(SIGPIPE,SIG_IGN);
    List_Init(list,people_node_t);
    struct sockaddr_in cliaddr,servaddr;
    socklen_t cliaddr_len;
    struct s1* temp;
    pthread_t pth1;
    char str[100];
    temp=(struct s1*)malloc(sizeof(struct s1));
    int epfd,sock_fd,nfds,conn_fd;
    sock_fd=socket(AF_INET,SOCK_STREAM,0);
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    servaddr.sin_port=htons(SERV_PORT);

    int opt = 1;
    setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));
    bind(sock_fd,(struct sockaddr*)&servaddr,sizeof(servaddr));
    listen(sock_fd,MAX_CONTECT_SIZE);
    struct epoll_event ev,events[10];
    epfd=epoll_create(MAX_CONTECT_SIZE);
    ev.data.fd= sock_fd;
    int connect_size=0;
    ev.events =EPOLLIN;
    epoll_ctl(epfd,EPOLL_CTL_ADD,sock_fd,&ev);
    connect_size++;
    for(;;)
    {   
        nfds = epoll_wait(epfd,events,EVENTS_MAX_SIZE,-1);//等待可写事件
        for(int i=0;i<nfds;i++)
        {
            if(events[i].data.fd==sock_fd)       //服务器套接字接收到一个连接请求
            {
                if(connect_size>MAX_CONTECT_SIZE)
                {
                    printf("%d %d\n",connect_size,nfds);
                    sleep(3);
                    perror("到达最大连接数!\n");
                    break;
               //     continue;
                }
                cliaddr_len=sizeof(cliaddr);
                conn_fd=accept(events[i].data.fd,(struct sockaddr*)&cliaddr,&cliaddr_len);
                if(conn_fd<=0)
                {
                    perror("error in accept\n");
                    printf("%s\n",strerror(errno));
                 //   continue;
                 break;
                }
                 connect_size++;
                 printf("received from %s at PORT %d\n",inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),ntohs(cliaddr.sin_port));
                

                ev.data.fd= conn_fd;
                ev.events =EPOLLIN | EPOLLONESHOT | EPOLLRDHUP;
                epoll_ctl(epfd,EPOLL_CTL_ADD,conn_fd,&ev);

            }
/*       
*/
            else{
                temp->epfd=epfd;
                temp->conn_fd=events[i].data.fd;
                pth1=pthread_create(&pth1,NULL,solve,temp);
            }
        }
    }
    close(sock_fd);
    List_Destroy(list,people_node_t);
}

serverfun.c

#include"mysqlc.h"
extern people_list_t list;
extern pthread_mutex_t mutex2;
void my_err(const char *error_string, int line)
{
    fprintf(stderr, "line:%d",line);
    perror(error_string);
    
}
MYSQL accept_mysql(void)
{
	MYSQL               mysql;
	
	if(NULL == mysql_init(&mysql)){
		my_err("mysql_init", __LINE__);
	}

	//初始化数据库
	if(mysql_library_init(0, NULL, NULL) != 0){
		my_err("mysql_library_init", __LINE__);
	}

	//连接数据库
	if(NULL == mysql_real_connect(&mysql, "127.0.0.1", "root", "12345", "etc", 0, NULL, 0)){
		my_err("mysql_real_connect", __LINE__);
	}

	//设置中文字符集
	if(mysql_set_character_set(&mysql, "utf8") < 0){
		my_err("mysql_set_character_set", __LINE__);
	}
	
	return mysql;
}
char* getname(int id)
{
	people_node_t* p;
	pthread_mutex_lock(&mutex2);
	List_ForEach(list,p)
	{
		if (p->data.id==id)
		{
			pthread_mutex_unlock(&mutex2);
		return p->data.name;
		}
	}
		pthread_mutex_unlock(&mutex2);
	return NULL;
}


ssize_t						/* Read "n" bytes from a descriptor. */
readn(int fd, void *vptr, size_t n)
{
	size_t	nleft;
	ssize_t	nread;
	char	*ptr;
 
	ptr = vptr;
	nleft = n;
	while (nleft > 0) {
		if ( (nread = read(fd, ptr, nleft)) < 0) {
			if (errno == EINTR)
				nread = 0;		/* and call read() again */
			else
				return(-1);
		} else if (nread == 0)
			break;				/* EOF */
 
		nleft -= nread;
		ptr   += nread;
	}
	return(n - nleft);		/* return >= 0 */
}
char* genRandomString(int length)
{
	int flag, i;
	char* string;
	srand((unsigned) time(NULL ));
	if ((string = (char*)malloc(length)) == NULL )
	{
		perror("Malloc failed!flag:14\n");
		return NULL ;
	}
 
	for (i = 0; i < length - 1; i++)
	{
		flag = rand() % 3;
		switch (flag)
		{
			case 0:
				string[i] = 'A' + rand() % 26;
				break;
			case 1:
				string[i] = 'a' + rand() % 26;
				break;
			case 2:
				string[i] = '0' + rand() % 10;
				break;
			default:
				string[i] = 'x';
				break;
		}
	}
	string[length - 1] = '\0';
	return string;
}
int getcfd(int id) //遍历链表查找在线人的fd
{
	people_node_t* p;
		pthread_mutex_lock(&mutex2);
	List_ForEach(list,p)
	{
		if (p->data.id==id)
		{
				pthread_mutex_unlock(&mutex2);
		return p->data.fd;
		}
	}
		pthread_mutex_unlock(&mutex2);
	return 0;
}
int getstatus(int id)  //遍历链表并查找在线状态
{
	people_node_t* p;
	pthread_mutex_lock(&mutex2);
	List_ForEach(list,p)
	{
		if (p->data.id==id)
		{
		pthread_mutex_unlock(&mutex2);
		return 1;
		}
	}
		pthread_mutex_unlock(&mutex2);
	return 0;
}
int close_mysql(MYSQL mysql)
{
	mysql_close(&mysql);
	mysql_library_end();
	printf("end\n");
	return 0;
}
int use_mysql(const char *name,const char *password,MYSQL mysql1)
{
	
	char string[50];
	sprintf(string,"select*from 用户数据 where 用户名=\"%s\"",name);
	int                 i;
	int                 ret;
	unsigned int        num_fields;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	MYSQL_FIELD         *field;

	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
			num_fields = mysql_num_fields(result);
			row = mysql_fetch_row(result);			
			if (!row)
			{
				return 0;
			}
					if(row[2]){
						if (strcmp(password,row[2])==0)
						{
							return 1;
						}
						else {
							return 0;
						}
					//	printf("%-20s", row[1]);
					}
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_4(int id,MYSQL mysql1)
{
	char string[50];
	sprintf(string,"select uid from 用户数据 where uid=%d;",id);
	int ret;
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	ret=mysql_query(&mysql,string);
	if (!ret)
	{
		result = mysql_store_result(&mysql);
		if(result){
			if ((row=mysql_fetch_row(result)))
			{
				return 1;
			}

		}
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;

}
int use_mysql_5(struct work temp,MYSQL mysql1)
{
	char string[50];
	sprintf(string,"insert into requst values(0,%d,%d,1)",temp.sid,temp.rid);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	ret=mysql_query(&mysql,string);
	if (!ret)
	{
		return 1;
	}
	else{
		printf("query error\n");
		return -1;
	}

}
char* use_mysql_7(int id,MYSQL mysql1)
{
	char string[50];
	sprintf(string,"select 用户名 from 用户数据 where uid=%d;",id);
	int ret;
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	ret=mysql_query(&mysql,string);
	if (!ret)
	{
		result = mysql_store_result(&mysql);
		if(result){
			if ((row=mysql_fetch_row(result)))
			{

				return row[0];
			}

		}
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return NULL;
	}
	return NULL;

}
int use_mysql_17(int id,MYSQL mysql1)
{
		
	char string[120];
	sprintf(string,"select pid,groupmates.gid,name,power from groupmates,grouplist where pid=%d and groupmates.gid=grouplist.gid",id);
	printf("%s\n",string);
	int                 ret;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'p',0,0,"","",0,""};
	
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
				int send_fd;
				send_fd=getcfd(id);
					while((row = mysql_fetch_row(result))){
					temp.rid=atoi(row[1]);
					strcpy(temp.name,row[2]);
					temp.ret=atoi(row[3]);
					send(send_fd,&temp,sizeof(temp),0);
					}
					temp.rid=0;
					send(send_fd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_3(int id,MYSQL mysql1)
{
		
	char string[120];
	sprintf(string,"select distinct uid,用户名 FROM 用户数据,friend WHERE friend.sid=%d AND 用户数据.uid=friend.rid ORDER BY uid",id);
	printf("%s\n",string);
	int                 i;
	int                 ret;
	unsigned int        num_rows;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'c',0,0,"","",0};
	
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
			num_rows = mysql_num_rows(result);
			
				int i=0;
				int send_fd;	
					send_fd=getcfd(id);
					while((row = mysql_fetch_row(result))){
					temp.rid=atoi(row[0]);
					strcpy(temp.name,row[1]);
					temp.ret=getstatus(temp.rid);
					send(send_fd,&temp,sizeof(temp),0);
					i++;
					}
					temp.rid=0;
					send(send_fd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_21(int gid,int cfd,MYSQL mysql1)
{
		
	char string[120];
	sprintf(string,"select distinct pid,power,用户名 from groupmates,用户数据 where pid=uid and gid=%d;",gid);
	printf("%s\n",string);
	int                 i;
	int                 ret;
	unsigned int        num_rows;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'r',0,0,"","",0};
	
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
			num_rows = mysql_num_rows(result);
					while((row = mysql_fetch_row(result))){
					temp.rid=atoi(row[0]);
					strcpy(temp.name,row[2]);
					temp.ret=atoi(row[1]);
					send(cfd,&temp,sizeof(temp),0);
					}
					temp.rid=0;
					send(cfd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_27(int gid,int sid,int cfd,MYSQL mysql1)
{
		
	char string[120];
	sprintf(string,"select sid,gmes from gmes where rid=%d and gid =%d and type=1",sid,gid);
	printf("%s\n",string);
	int                 i;
	int                 ret;
	unsigned int        num_rows;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'u',0,0,"","",0};
	
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
					while((row = mysql_fetch_row(result))){
					temp.sid=atoi(row[0]);
					strcpy(temp.mes,row[1]);
					send(cfd,&temp,sizeof(temp),0);
					}
					temp.sid=0;
					send(cfd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_29(struct work s1,char *filename,MYSQL mysql1)
{
		
	char string[120];
	sprintf(string,"insert into file values(0,%d,%d,\"%s\",\"%s\",%d,0)",s1.sid,s1.rid,s1.name,filename,s1.ret);
	printf("%s\n",string);
	int                 i;
	int                 ret;
	unsigned int        num_rows;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'v',0,0,"","",0};
	temp.sid=s1.sid,strcpy(temp.name,s1.name);
	temp.ret=s1.ret;temp.rid=0;//暂时用rid承担是否已下载过
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		if (getstatus(s1.rid))
		{
			send(getcfd(s1.rid),&temp,sizeof(temp),0);
		}
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_30(int sid,MYSQL mysql1)
{
		
	char string[120];
	int cfd=getcfd(sid);
	sprintf(string,"select sid,filename,address,size,type from file where rid=%d",sid);
	printf("%s\n",string);
	int                 i;
	int                 ret;
	unsigned int        num_rows;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'v',0,0,"","",0};
	ret = mysql_query(&mysql, string);
	if(!ret){
			result = mysql_store_result(&mysql);
			if (result)
			{	
				while((row=mysql_fetch_row(result)))
				{
				temp.sid=atoi(row[0]);
				temp.rid=atoi(row[4]);
				temp.ret=atoi(row[3]);
				strcpy(temp.name,row[1]);
				send(cfd,&temp,sizeof(temp),0);
				}
				temp.sid=0;
				send(cfd,&temp,sizeof(temp),0);
			}
			mysql_free_result(result);

	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_31(struct work s1,MYSQL mysql1)
{
		
	char string[120];
	char string1[120];
	sprintf(string,"select id,address from file where sid=%d and rid=%d and filename=\"%s\" and size=%d",s1.sid,s1.rid,s1.name,s1.ret);
	printf("%s\n",string);
	int                 i;
	int id;
	int fd;
	int                 ret;
	unsigned int        num_rows;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp=s1;
	temp.tye='w';
	send(getcfd(s1.rid),&temp,sizeof(temp),0);
	ret = mysql_query(&mysql, string);
	if(!ret){
		result=mysql_store_result(&mysql);
		if (result)
		{
			row=mysql_fetch_row(result);
			id=atoi(row[0]);
			sprintf(string1,"update file set type=1 where id=%d",id);
			mysql_query(&mysql, string1);
			fd=open(row[1],O_RDONLY,0664);
			if (fd==-1)
			{
				printf("open %s\n failed\n",row[1]);
				perror("open");
			}
			struct stat stat_buf;
			fstat(fd,&stat_buf);
			sendfile(getcfd(s1.rid),fd,NULL,stat_buf.st_size);
			close(fd);
		}
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_32(struct work s1,MYSQL mysql1) //搁置
{
		
char string[120];
	char string1[120];
	sprintf(string,"select id,address from file where sid=%d and rid=%d and filename=\"%s\" and size=%d",s1.sid,s1.rid,s1.name,s1.ret);
	printf("%s\n",string);
	int                 i;
	int id;
	int fd;
	int                 ret;
	unsigned int        num_rows;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	ret = mysql_query(&mysql, string);
	if(!ret){
		result=mysql_store_result(&mysql);
		if (result)
		{
			row=mysql_fetch_row(result);
			id=atoi(row[0]);
			sprintf(string1,"delete from file where id=%d",id);
			mysql_query(&mysql, string1);
			remove(row[1]);
		}
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_28(int gid,int sid,int cfd,MYSQL mysql1)
{
		
	char string[120];
	sprintf(string,"select sid,gid,gmes from gmes where rid=%d and type=0",sid);
	printf("%s\n",string);
	int                 i;
	int                 ret;
	unsigned int        num_rows;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'t',0,0,"","",0};
	
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
					while((row = mysql_fetch_row(result))){

					temp.sid=atoi(row[0]);
					temp.rid=atoi(row[1]);
					strcpy(temp.mes,row[2]);
					send(cfd,&temp,sizeof(temp),0);
					}
					temp.sid=0;
					send(cfd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_24(int gid,MYSQL mysql1) //还没完,把聊天记录也一删除
{
	char string[60];
	char string1[60];
	sprintf(string,"delete from groupmates where gid=%d",gid);
	sprintf(string1,"delete from grouplist where gid=%d",gid);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	if (!mysql_query(&mysql,string))
	{
		if (!mysql_query(&mysql,string1))
		{
			
			return 1;
		}
	return 0;
	}
	return 0;
}
int use_mysql_23(struct work s1,MYSQL mysql1)
{
	char string[60];
	sprintf(string,"delete from groupmates where gid=%d and pid=%d",s1.sid,s1.rid);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	if (!mysql_query(&mysql,string))
	{
		return 1;
	}
	return 0;
}
int use_mysql_22(struct work s1,MYSQL mysql1)
{
	char string[60];
	sprintf(string," update groupmates set power=1 where pid=%d and gid=%d",s1.rid,s1.sid);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	if (!mysql_query(&mysql,string))
	{
		return 1;
	}
	return 0;
}
int use_mysql_6(int id,MYSQL mysql1)
{
		
	char string[150];
	sprintf(string,"select distinct sid,rid,type,用户数据.用户名 from requst,用户数据 where rid=%d and sid=uid;",id);
	int                 ret;
	unsigned int        num_rows;
	unsigned int        num_feids;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'g',0,0,"","",0};
	
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
			num_rows = mysql_num_rows(result);
			num_feids=mysql_num_fields(result);
				int send_fd;
					send_fd=getcfd(id);
					while((row = mysql_fetch_row(result))){
					temp.rid=atoi(row[0]);
					temp.ret=atoi(row[2]);
					strcpy(temp.name,row[3]);
					temp.sid=1;
					send(send_fd,&temp,sizeof(temp),0);
					}
					temp.sid=0;
					send(send_fd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_18(int gid,int sid,MYSQL mysql1)
{
		
	char string[150];
	sprintf(string,"select distinct sid,用户名,type from 用户数据,grequst where gid=%d and sid=uid;",gid);
	int                 ret;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'q',0,0,"","",0};
	
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
				int send_fd;
					send_fd=getcfd(sid);
					while((row = mysql_fetch_row(result))){
					temp.ret=atoi(row[2]);
					strcpy(temp.name,row[1]);
					temp.sid=atoi(row[0]);
					send(send_fd,&temp,sizeof(temp),0);
					}
					temp.sid=0;
					send(send_fd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_13(int id,MYSQL mysql1)
{
		
	char string[150];
	sprintf(string,"select sid,rid,mes from smes where sid = %d or rid =%d and type=1",id,id);
	printf("%s\n",string);
	int                 ret;
	unsigned int        num_rows;
	unsigned int        num_feids;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'m',0,0,"","",0};
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
				int send_fd;

					while((row = mysql_fetch_row(result))){
					temp.sid=atoi(row[0]);
					temp.rid=atoi(row[1]);
					strcpy(temp.mes,row[2]);
					send_fd=getcfd(id);
					send(send_fd,&temp,sizeof(temp),0);
					}
					temp.sid=0;
					send(send_fd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_14(int id,MYSQL mysql1)
{
		
	char string[150];
	sprintf(string,"select sid,rid,mes from smes where rid =%d and type=0",id);
	printf("%s\n",string);
	int                 ret;
	unsigned int        num_rows;
	unsigned int        num_feids;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'k',0,0,"","",0};
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
				int send_fd;

					while((row = mysql_fetch_row(result))){
					temp.sid=atoi(row[0]);
					temp.rid=atoi(row[1]);
					strcpy(temp.mes,row[2]);
					send_fd=getcfd(id);
					send(send_fd,&temp,sizeof(temp),0);
					}
					temp.sid=0;
					send(send_fd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_16(struct work temp,MYSQL mysql1)
{
		
	char string[150];
	sprintf(string,"select gid from grouplist where gid =%d",temp.rid);
	char string1[150];
	sprintf(string1,"insert into grequst values(0,%d,%d,1)",temp.sid,temp.rid);
	int                 ret;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	int send_fd=getcfd(temp.sid);
	struct work test={'x',0,0,"","",0,""};
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
				row = mysql_fetch_row(result);
					if (row)
					{
						ret=mysql_query(&mysql,string1);
							if (!ret)
							{
								test.ret=1;
							}
							else {
								printf("error:%s",string1);
							}
						
					}
					else test.ret=0;
					send(send_fd,&test,sizeof(test),0);
				}

				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_10(struct work temp,MYSQL mysql1) //未测试 
{
	char string[50];
	char string1[100];
	char string2[100];
	sprintf(string,"insert into requst values(0,%d,%d,%d)",temp.sid,temp.rid,temp.ret);
	sprintf(string1,"delete from friend where sid=%d and rid=%d",temp.sid,temp.rid);
	sprintf(string2,"delete from friend where sid=%d and rid=%d",temp.rid,temp.sid);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	if (!mysql_query(&mysql,string))
	{
		if (!mysql_query(&mysql,string1))
		{
			if (!mysql_query(&mysql,string2))
			{
				return 1;
			}
		}
	}
	return 0;
}
int use_mysql_9(struct work temp,MYSQL mysql1)
{
	char string[60];
	sprintf(string,"delete from requst  where sid=%d and rid=%d and type=%d",temp.sid,temp.rid,temp.ret);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	if (!mysql_query(&mysql,string))
	{
		return 1;
	}
	return 0;
}
int use_mysql_20(struct work temp,MYSQL mysql1)
{
	char string[60];
	sprintf(string,"delete from grequst  where sid=%d and gid=%d and type=%d",temp.sid,temp.rid,temp.ret);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	if (!mysql_query(&mysql,string))
	{
		return 1;
	}
	return 0;
}
int use_mysql_8(struct work temp,MYSQL mysql1)
{
	char string[50];
	char string1[50];
	char string2[60];
	sprintf(string,"insert into friend values(0,%d,%d)",temp.sid,temp.rid);
	sprintf(string1,"insert into friend values(0,%d,%d)",temp.rid,temp.sid);
	sprintf(string2,"delete from requst  where sid=%d and rid=%d and type=%d",temp.sid,temp.rid,temp.ret);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	if (!mysql_query(&mysql,string))
	{
		if (!mysql_query(&mysql,string1))
		{
			if (!mysql_query(&mysql,string2))
			{
				return 1;
			}
		}
	}
	return 0;
}
int use_mysql_12(struct work temp,MYSQL mysql1)
{
	char string[1200];
	sprintf(string,"update smes set type = 1 where sid=%d and rid=%d and mes=\"%s\"",temp.sid,temp.rid,temp.mes);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	ret=mysql_query(&mysql,string);
	if (!ret)
	{
		return 1;
	}
	else{
		printf("query error\n");
		return -1;
	}

}
int use_mysql_26(struct work temp,MYSQL mysql1)
{
	char string[1200];
	sprintf(string,"update gmes set type = 1 where sid=%d and rid=%d and gid=%d and gmes=\"%s\"",temp.sid,temp.ret,temp.rid,temp.mes);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	ret=mysql_query(&mysql,string);
	if (!ret)
	{
		return 1;
	}
	else{
		printf("query error\n");
		return -1;
	}

}
int use_mysql_11(struct work temp,MYSQL mysql1)
{
	char string[1200];
	sprintf(string,"insert into smes values(0,%d,%d,\"%s\",%d)",temp.sid,temp.rid,temp.mes,temp.ret);
	printf("%s\n",string);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	ret=mysql_query(&mysql,string);
	if (!ret)
	{
		return 1;
	}
	else{
		printf("query error\n");
		return -1;
	}

}
int use_mysql_1(const char *name,const char *password,MYSQL mysql1) //注册,先看有没有,再插入
{
	
	char string[50];
	char string1[100];
	sprintf(string,"select*from 用户数据 where 用户名=\"%s\"",name);
	sprintf(string1,"insert into 用户数据 values(NULL,\"%s\",\"%s\")",name,password);
	int                 i;
	int                 ret;
	unsigned int        num_fields;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	int ret1;
	printf("%s\n",string1);
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
			row = mysql_fetch_row(result);			
					if (!row)
					{
						ret1=mysql_query(&mysql,string1);
						if (!ret1)
						{
							return 1;
						}
						else return 0;
					}
					else{
						return 0;
					}
				}
				printf("sa\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_15(struct work temp,MYSQL mysql1)
{
		
	char string[150];
	char string1[150];
	char string2[150];
	sprintf(string,"select gid from grouplist where name=\"%s\"",temp.name);
	sprintf(string1,"insert into grouplist values(0,%d,\"%s\")",temp.sid,temp.name);
	int                 ret;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_RES           *result1 = NULL;
	MYSQL_ROW           row;
	int send_fd=getcfd(temp.sid);
	struct work test={'o',0,0,"","",0};
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
				row=mysql_fetch_row(result);
				if (!row)
				{	
					ret=mysql_query(&mysql,string1);
					
						if (!ret)
						{
							ret=mysql_query(&mysql,string);
							if (!ret)
							{
								printf("string:%s\n",string);
								result1=mysql_store_result(&mysql);
								if (result1)
								{
									row=mysql_fetch_row(result1);
									temp.rid=atoi(row[0]);
									sprintf(string2,"insert into groupmates values(%d,%d,2)",temp.rid,temp.sid);
									ret=mysql_query(&mysql,string2);
									if (!ret)
									{
										strcpy(test.name,temp.name);
										test.ret=1;
										test.rid=temp.rid;
										send(send_fd,&test,sizeof(test),0);
									}
									else printf("error %s\n",string2);
								}
									mysql_free_result(result1);
								
							}
						}
						else {
							printf("qurry fail%s",string1);
						}
					
				}
				else{	
					test.ret=0;
					send(send_fd,&test,sizeof(test),0);
				}
				}
				mysql_free_result(result);
				printf("\n");		
	}
	else{
		printf("query fail %s\n",string);
		return -1;
	}
	return 0;
}
int use_mysql_25(struct work s1,MYSQL mysql1)
{
		
	char string[120];
	char string1[1300];
	sprintf(string,"select distinct pid,用户名 from groupmates,用户数据 where gid=%d and pid=uid;",s1.rid);
	printf("%s\n",string);
	int                 ret;
	int id;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	struct work temp={'t',0,0,"","",0};
	
//	mysql_query(&mysql,"use etc");
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
					int send_fd;
					while((row = mysql_fetch_row(result))){
							temp.ret=0;
							id=atoi(row[0]);
							if (id==s1.sid)
							{
								temp.ret=1;
							}
							else{
							if (getstatus(id))
								{
									temp.sid=s1.sid;
									temp.rid=s1.rid;
									strcpy(temp.name,row[1]);
									strcpy(temp.mes,s1.mes);
									send_fd=getcfd(id);
									send(send_fd,&temp,sizeof(temp),0);
								}
							}
							sprintf(string1,"insert into gmes values(0,%d,%d,%d,\"%s\",%d)",s1.rid,s1.sid,id,s1.mes,temp.ret);
							if (mysql_query(&mysql, string1))
								{
									printf("query fail\n");
									return -1;
								}
							}
//					temp.sid=0;
//					send(send_fd,&temp,sizeof(temp),0);
				}
				printf("\n");		
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int use_mysql_19(struct work temp,MYSQL mysql1)
{
	char string[50];
	char string2[60];
	char string3[60];
	sprintf(string3,"select *from groupmates where gid=%d and pid=%d",temp.rid,temp.sid);
	sprintf(string,"insert into groupmates values(%d,%d,0)",temp.rid,temp.sid);
	sprintf(string2,"delete from grequst  where sid=%d and gid=%d and type=%d",temp.sid,temp.rid,temp.ret);
	MYSQL mysql=mysql1;
	MYSQL_RES *result=NULL;
	MYSQL_ROW row;
	int ret;
	if (!mysql_query(&mysql,string3))
	{
		result = mysql_store_result(&mysql);
		if(result){
			if (!(row = mysql_fetch_row(result)))
			{

				
				mysql_free_result(result);
				return 0;
			}

					
				}
				printf("\n");
		mysql_free_result(result);
	}
	if (!mysql_query(&mysql,string))
	{
			if (!mysql_query(&mysql,string2))
			{
				return 1;
			}
	}
	return 0;
}
int use_mysql_2(const char *name,MYSQL mysql1)
{
	char string[50];
	sprintf(string,"select uid from 用户数据 where 用户名=\"%s\"",name);
	int                 ret;
	unsigned int        num_fields;
	MYSQL               mysql = mysql1;
	MYSQL_RES           *result = NULL;
	MYSQL_ROW           row;
	MYSQL_FIELD         *field;
	mysql_query(&mysql,"use etc");
	//printf("%s\n",string);
	ret = mysql_query(&mysql, string);
	if(!ret){
		result = mysql_store_result(&mysql);
		if(result){
			num_fields = mysql_num_fields(result);
			if (!(row = mysql_fetch_row(result)))
			{
				return 0;
			}
			return atoi(row[0]);
					
				}
				printf("\n");
		mysql_free_result(result);
	}
	else{
		printf("query fail\n");
		return -1;
	}
	return 0;
}
int judege(const char *name,const char *password)
{
  MYSQL a;
    a=accept_mysql();
    int ret=use_mysql(name,password,a);
    close_mysql(a);
    return ret;
}
int judegeon(const char *name,const char *password)
{
  MYSQL a;
    a=accept_mysql();
    int ret=use_mysql_1(name,password,a);
    close_mysql(a);
    return ret;
}
void getmyfriend(int id) //查找所有好友并返回
{
	MYSQL a;
    a=accept_mysql();
	int ret;
    ret=use_mysql_3(id,a);
    close_mysql(a);
}
void getmyrequst(int id)
{
	MYSQL a;
    a=accept_mysql();
	int ret;
    ret=use_mysql_6(id,a);
    close_mysql(a);
}
void getmygrequst(int gid,int sid)
{
	MYSQL a;
    a=accept_mysql();
	int ret;
    ret=use_mysql_18(gid,sid,a);
    close_mysql(a);
}
char *yourname(int id)
{
	MYSQL a;
	char *c;
    a=accept_mysql();
    c=use_mysql_7(id,a);
    close_mysql(a);
	return c;
}
int find_byname(const char*name) //通过用户名查找id
{
	 MYSQL a;
    a=accept_mysql();
    int ret=use_mysql_2(name,a);
    close_mysql(a);
    return ret;
}
void add_friends(struct work temp) //储存加好友信息
{
	MYSQL a;
    a=accept_mysql();
	int ret;
    ret=use_mysql_5(temp,a);
	if (getstatus(temp.rid))
	{
		int cfd=getcfd(temp.rid);
		printf("cfd:%d",cfd);
		strcpy(temp.name,getname(temp.sid));
		send(cfd,&temp,sizeof(temp),0);
	}
    close_mysql(a);
}
void agree(struct work temp)
{
	MYSQL a;
	int ret;
    a=accept_mysql();
    use_mysql_8(temp,a);
    close_mysql(a);
}
void disagree(struct work temp)
{
	int ret;
		MYSQL a;
    a=accept_mysql();
    ret=use_mysql_9(temp,a);
    close_mysql(a);
}
void agreeg(struct work temp)
{
	MYSQL a;
	int ret;
    a=accept_mysql();
    use_mysql_19(temp,a);
    close_mysql(a);
}
void disagreeg(struct work temp)
{
	int ret;
		MYSQL a;
    a=accept_mysql();
    ret=use_mysql_20(temp,a);
    close_mysql(a);
}
void delete_friend(struct work temp)
{
		MYSQL a;
    a=accept_mysql();
    use_mysql_10(temp,a);
	if (getstatus(temp.rid))
	{
		int cfd=getcfd(temp.rid);
		printf("cfd:%d",cfd);
		temp.tye='f';
		strcpy(temp.name,getname(temp.sid));
		send(cfd,&temp,sizeof(temp),0);
	}
    close_mysql(a);
}
void ssend_mes(struct work temp)
{
	MYSQL a;
    a=accept_mysql();
	int ret;
	if (getstatus(temp.rid))
	{
		int cfd=getcfd(temp.rid);
		send(cfd,&temp,sizeof(temp),0);
	}
	ret=use_mysql_11(temp,a);
    close_mysql(a);
}
void gsend_mes(struct work s1)
{
	MYSQL a;
    a=accept_mysql();
	use_mysql_25(s1,a);
    close_mysql(a);
}
void read_mes(struct work temp)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_12(temp,a);
    close_mysql(a);
}
void read_gmes(struct work s1)
{
		MYSQL a;
    a=accept_mysql();
    use_mysql_26(s1,a);
    close_mysql(a);
}
void sendallmes(int id)

 {
	MYSQL a;
    a=accept_mysql();
    use_mysql_13(id,a);
    close_mysql(a);
 }
void getallgmes(int gid,int sid,int cfd)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_27(gid,sid,cfd,a);
    close_mysql(a);
}
void getallngmes(int gid,int sid,int cfd)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_28(gid,sid,cfd,a);
    close_mysql(a);
}
void getallnmes(int id)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_14(id,a);
    close_mysql(a);
}
void createg(struct work temp)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_15(temp,a);
    close_mysql(a);
}
void joingroups(struct work temp)
{
		MYSQL a;
    a=accept_mysql();
    use_mysql_16(temp,a);
    close_mysql(a);
}
void getmygroup(int id)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_17(id,a);
    close_mysql(a);
}
void getmates(int gid,int cfd)
{
	MYSQL a;
    a=accept_mysql();
	int ret;
    ret=use_mysql_21(gid,cfd,a);
    close_mysql(a);
}
void savefile(struct work s1,char *filename)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_29(s1,filename,a);
    close_mysql(a);
}
void setadmin(struct work s1,int cfd)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_22(s1,a);
    close_mysql(a);
}
void delmate(struct work s1,int cfd)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_23(s1,a);
    close_mysql(a);
}
void killgroup(int gid)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_24(gid,a);
    close_mysql(a);
}
void sendfilelist(struct work s1)
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_30(s1.sid,a);
    close_mysql(a);
}
void send_file(struct work s1)   //搁置
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_31(s1,a);
    close_mysql(a);
}
void delete_file(struct work s1) //搁置
{
	MYSQL a;
    a=accept_mysql();
    use_mysql_32(s1,a);
    close_mysql(a);
}
int ishe(int id,struct s1 *s) //判断是否存在id
{
	MYSQL a;
    a=accept_mysql();
    int ret=use_mysql_4(id,a);
    close_mysql(a);
	struct work ss;
	ss.tye='d';
	ss.ret=ret;
	send(s->conn_fd,&ss,sizeof(ss),0);
    return ret;
}

c.c

#include "c.h"

 int myid;
 int siliao=0;
 int qunliao=0;
 int allcansee=-1;
#define SERVER_ADDR     "192.168.30.121"
#define SERVER_PORT     9000
 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex4 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex5 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex6 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex7 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex8 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex9 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex10 = PTHREAD_MUTEX_INITIALIZER;
yan_list_t list1=NULL;
people_list_t list=NULL;
people_list_t glist=NULL;
mes_list_t mes1=NULL;
mes_list_t mes2=NULL;
mes_list_t gmes1=NULL;
mes_list_t gmes2=NULL;
file_list_t flist=NULL;
group_list_t group1=NULL;
yan_list_t gyan=NULL;
black_list_t blacklist=NULL;
int main()
{
     signal(SIGPIPE,SIG_IGN);
    List_Init(blacklist,struct black_node);
    List_Init(list1,struct yan_node);
    List_Init(flist,struct file_node);
    List_Init(gyan,struct yan_node);
    List_Init(list,struct people_node);
    List_Init(glist,struct people_node);
    List_Init(mes1,struct mes_node);
    List_Init(mes2,struct mes_node);
    List_Init(gmes1,struct mes_node);
    List_Init(gmes2,struct mes_node);
    List_Init(group1,struct group_node);
    int cfd = 0;
    struct sockaddr_in saddr;
    char buf[BUFSIZ] = {0};
    int i = 0,n = 0;
 
    cfd = socket(AF_INET,SOCK_STREAM,0);
 
    bzero(&saddr,sizeof(saddr));
    saddr.sin_family = AF_INET;
    inet_pton(AF_INET,SERVER_ADDR,&saddr.sin_addr.s_addr);
    saddr.sin_port = htons(SERVER_PORT);
 
    while ((connect(cfd,(struct sockaddr*)&saddr,sizeof(saddr)))!=0)
    {
        printf ("服务器未响应...........\n");
        sleep(3);
        system("clear");
    }
    int t=5;
    struct work test={'a',0,0,"","",0};
    char op;
    int ret;
    while(1)
    {
        system("clear");
        ret=0;
        printf("============================ 欢迎使用聊天室 ============================\n");
        printf("                        输入'1'来登陆一个已注册帐号\n");
        printf("                        输入'2'来注册一个帐号\n");
        printf("                        输入'3'退出本聊天室\n");
        fflush(stdin);
        scanf("%c",&op);
        while(getchar()!='\n');
        switch(op){
        case '1':
        ret=SysLogin(cfd);
        break;
        case '2':
        SysLogon(cfd);
        break;
        case '3':
        close(cfd);
        return 0;
        break;
        default:
        printf("%c不是一个合法选项\n",op);
        }
        if (ret==1)
        {
            break;
        }
    }
    pthread_t pid1;
    int status;
    int simple=0;
    pthread_create(&pid1,NULL,ralt,&cfd);
    struct work temp={'c',0,0,"","",0};
    temp.sid=myid;
    send(cfd,&temp,sizeof(struct work),0);
    temp.tye='g';
    send(cfd,&temp,sizeof(struct work),0);
    temp.tye='m';
     send(cfd,&temp,sizeof(struct work),0);
     temp.tye='n';
     send(cfd,&temp,sizeof(struct work),0);
     temp.tye='5';
     send(cfd,&temp,sizeof(struct work),0);
     temp.tye='q';
    send(cfd,&temp,sizeof(struct work),0);
      system("clear");
    sleep(2);
    while(1)
    {
        int i=0;
        mes_node_t *cus;
        yan_node_t *cua;
        file_node_t *cub;
        system("clear");
        printf("============================ 欢迎使用聊天室 ============================\n");
        printf("ID:%d\n",myid);
              List_ForEach(mes1,cus)
        {
            i++;
        }
         printf("您有%d条私聊消息未读\n",i);
        i=0;
        List_ForEach(list1,cua)
        {
            i++;
        }
           printf("您有%d条验证请求未处理\n",i);
        i=0;
        List_ForEach(flist,cub)
        {
            i++;
        }
        printf("您有%d个文件待处理\n",i);
        printf("                        输入'a'来查看好友列表(状态)\n");
        printf("                        输入'b'来开启一个私聊(输入id号)\n");
        printf("                        输入'c'来查看消息记录\n");
        printf("                        输入'd'来管理好友\n");
        printf("                        输入'e'来创建一个群聊\n");
        printf("                        输入'f'来加入一个群聊\n");
        printf("                        输入'g'来查看已加入的群组\n");
        printf("                        输入'h'来进行群组管理\n");
        printf("                        输入'i'来进入一个群聊\n");
        printf("                        输入'j'来查看群组历史记录\n");
        printf("                        输入'k'来传输文件\n");
        printf("                        输入'z'来退出\n");
        
        fflush(stdin);
        scanf("%c",&op);
        while(getchar()!='\n');
        switch (op)
        {
        case 'a':
        fetchallfriend(cfd);
        break;
        case 'b':
        chatwithf(cfd);
        break;
        case 'c':
        fetchallmes(cfd);
        break;
        case 'd':
        managefriend(cfd);
        break;
        case 'e':
        creategroup(cfd);
        break;
        case 'f':
        joingroup(cfd);
        break;
        case 'g':
        getgroup(cfd);
        break;
        case 'h':
        managegroup(cfd);
        break;
        case 'i':
        chatwithg(cfd);
        break;
        case 'j':
        grouphistory(cfd);
        break;
        case 'k':
        transfile(cfd);
   //     case 'l':
    //    block();
     //   break;
        break;
        case 'z':
        simple=1;
        break;
        default:
            printf("不是一个合法的选择,请重新输入\n");
            printf("输入回车键继续\n");
            break;
        }
        if (simple==1)
        {
            break;
        }
    }
    close(cfd);
    List_Destroy(list1,struct yan_node);
    List_Destroy(flist,struct file_node);
    List_Destroy(gyan,struct yan_node);
    List_Destroy(list,struct people_node);
    List_Destroy(glist,struct people_node);
    List_Destroy(mes1,struct mes_node);
    List_Destroy(mes2,struct mes_node);
    List_Destroy(gmes1,struct mes_node);
    List_Destroy(gmes2,struct mes_node);
    List_Destroy(group1,struct group_node);
    return 0;
}

cfun.c

#include "c.h"
extern int myid;
extern int allcansee;
extern int siliao;
extern int qunliao;
extern yan_list_t list1;
extern people_list_t list;
extern people_list_t glist;
extern file_list_t flist;
extern mes_list_t mes1;
extern mes_list_t mes2;
extern mes_list_t gmes1;
extern mes_list_t gmes2;
extern group_list_t group1;
extern yan_list_t gyan;
extern black_list_t blacklist;

extern pthread_mutex_t mutex;
extern pthread_mutex_t mutex1;
extern pthread_mutex_t mutex2;
extern pthread_mutex_t mutex3;
extern pthread_mutex_t mutex4;
extern pthread_mutex_t mutex5;
extern pthread_mutex_t mutex6;
extern pthread_mutex_t mutex7;
extern pthread_mutex_t mutex8;
extern pthread_mutex_t mutex9;
extern pthread_mutex_t mutex10;
void getgroupmates(int gid,int cfd)
{
      char a;
     int simple=0;
    while(1)
    {
        pthread_mutex_lock(&mutex10);
        allcansee=-1;
        pthread_mutex_unlock(&mutex10);
        List_Free(glist,people_node_t);
        struct work temp={'v',0,0,"","",0};
        temp.sid=gid;
        send(cfd,&temp,sizeof(struct work),0);
        
        while(1)
        {
             pthread_mutex_lock(&mutex10);
            if(allcansee==-1)
            {
                printf("等待服务器响应\n");
                sleep(1);
                 pthread_mutex_unlock(&mutex10);
                system("clear");
              
            }
            else { pthread_mutex_unlock(&mutex10);
                break;
            }   
        }

        system("clear");
        pthread_mutex_lock(&mutex6);
        people_node_t *p;
        printf("%-20s%-20s%-20s\n","id","用户名","身份");
        List_ForEach(glist,p)
        {
            printf("%-20d%-20s",p->data.id,p->data.name);
            if (p->data.status==2)
            printf("%-20s\n","群主");
            else if (p->data.status==1)
            printf("%-20s\n","管理员");
            else printf("%-20s\n","群成员");
            
        }
        pthread_mutex_unlock(&mutex6);
       
    //    printf("输入'1'来刷新状态\n");
        printf("输入'1'来退出查看\n");
        getgroupmates1:
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
        
            case '1':
            simple=1;
            break;
            default:
            printf("不是一个合法选项,请重新输入\n");
           goto getgroupmates1;
            break;
        }
        if (simple==1)
        break;
    }
    
}
int getch()
{
   int c = 0;
   struct termios org_opts, new_opts;
   int res = 0;
   //-----  store old settings -----------
   res = tcgetattr(STDIN_FILENO, &org_opts);
   assert(res == 0);
   //---- set new terminal parms --------
   memcpy(&new_opts, &org_opts, sizeof(new_opts));
   new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
   tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
   c = getchar();
   //------  restore old settings ---------
   res = tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
   assert(res == 0);
   return c;
}
void *ralt(void* temp)
{
    int i=0;
    int j=0;
    int k=0;
    int l=0;
    int m=0;
    int out;
    int n=0;
    int o=0;
    int p=0;
    int v=0;
    int q=0;
    int cfd=*(int *)temp;
    struct work s1;
    people_node_t *new=NULL;
    yan_node_t *old=NULL;
    file_node_t *file1=NULL;
    mes_node_t *nmes=NULL;
    mes_node_t *lmes=NULL;
    group_node_t *g=NULL;
    while(1)
    {
        recv(cfd,&s1,sizeof(struct work),0);
        switch (s1.tye)
        {
        case 'c':
            if (s1.rid==0)
            {
                i=0;
                 pthread_mutex_lock(&mutex10);
                allcansee=1;
                 pthread_mutex_unlock(&mutex10);
                pthread_mutex_unlock(&mutex);
                break;
            }
                if (i==0)
                pthread_mutex_lock(&mutex);
                i++;
                new=(people_node_t*)malloc(sizeof(people_node_t));
                new->data.id=s1.rid;
                strcpy(new->data.name,s1.name);
                new->data.status=s1.ret;
                
  //              printf("%-20d%-20s%-20d\n",s1.rid,s1.name,s1.ret);
                List_AddTail(list,new);                
        break;
        case 'd':
         pthread_mutex_lock(&mutex10);
            if (s1.ret==0)
            {
                allcansee=0;
            }
            else allcansee=1;
             pthread_mutex_unlock(&mutex10);
            break;
        case 'f': //'f'在后期考虑丢弃,因为此功能没啥用,验证消息不用单独来接
                old=(yan_node_t*)malloc(sizeof(yan_node_t));
                old->data.sid=s1.sid;
                strcpy(old->data.name,s1.name);
                old->data.type=s1.ret;
                old->data.xu=0;
                if (s1.ret==0)
                {   people_node_t *p,*ps;
                    pthread_mutex_lock(&mutex);
                    List_ForEach(list,p)
                    {
                        if(p->data.id==s1.sid)
                        {
                            break;
                        }
                    }
                    ps=p;
                    (p->prev)->next=p->next;
                    List_FreeNode(p);
                     pthread_mutex_unlock(&mutex);
                }
                printf("您有一条新的验证消息\n");
 //               printf("%-20d%-20s%-20d\n",s1.sid,s1.name,1);
                List_AddTail(list1,old);      
            break;
        case 'g':
            if (s1.sid==0)
            {
                printf("你有%d条验证消息等待处理\n",j);
                j=0;
                pthread_mutex_lock(&mutex10);
                allcansee=1;
                pthread_mutex_unlock(&mutex10);
                pthread_mutex_unlock(&mutex1);
                break;
            }
                if (j==0)
                pthread_mutex_lock(&mutex1);
                j++;
                old=(yan_node_t*)malloc(sizeof(yan_node_t));
                old->data.xu=j;
                old->data.sid=s1.rid;
                strcpy(old->data.name,s1.name);
                old->data.type=s1.ret;
  //              printf("%-20d%-20s%-20d\n",s1.rid,s1.name,s1.ret);
                List_AddTail(list1,old);                
        break;
        case 'k':
        if (siliao!=0)
        {
        
            if (s1.sid==siliao)
            {
                printf("\n                                        %s:%d\n","id:",s1.sid);
                printf("                                        %-45s\n",s1.mes);
                   nmes=(mes_node_t*)malloc(sizeof(mes_node_t));
                nmes->data.sid=s1.sid;
                strcpy(nmes->data.mes,s1.mes);  
                List_AddTail(mes2,nmes);
                 s1.tye='l';

            send(cfd,&s1,sizeof(s1),0);
            break;
            }
            else printf("id:%d给您发了一条新的消息",s1.sid);
            
        }
        if (s1.sid==0) //发送者id不可能为0,表示结束并放开锁
            {
                k=0;
                sleep(1);
                printf("您有%d条未读消息\n",k);
                pthread_mutex_unlock(&mutex2);
                break;
            }
                if (k==0)
                pthread_mutex_lock(&mutex2);
                k++;
                nmes=(mes_node_t*)malloc(sizeof(mes_node_t));
                nmes->data.sid=s1.sid;
                strcpy(nmes->data.mes,s1.mes);
                if(siliao==0)
                printf("id:%d给您发了一条新的消息\n",s1.sid);         
  //              printf("%-20d%-20s%-20d\n",s1.rid,s1.name,s1.ret);
                List_AddTail(mes1,nmes);                
        break;
        case 'm':
        if (s1.sid==0) //发送者id不可能为0,表示结束并放开锁
            {
                l=0;
                pthread_mutex_unlock(&mutex3);
                break;
            }
                if (l==0)
                pthread_mutex_lock(&mutex3);
                l++;
                lmes=(mes_node_t*)malloc(sizeof(mes_node_t));
                lmes->data.sid=s1.sid;
                lmes->data.rid=s1.rid;
                strcpy(lmes->data.mes,s1.mes);
                List_AddTail(mes2,lmes); 
        break;
        case 'o': 
        pthread_mutex_lock(&mutex10);
         if (s1.ret==0)
            {
                allcansee=0;
            }
            else {
                allcansee=1;
                printf("您创建的群组名为%s,ID号为%d",s1.name,s1.rid);
                }
                 pthread_mutex_unlock(&mutex10);
            break;
        case 'p':
        if (s1.rid==0) //发送者id不可能为0,表示结束并放开锁
        {
            m=0;
             pthread_mutex_lock(&mutex10);
            allcansee=1;
             pthread_mutex_unlock(&mutex10);
            pthread_mutex_unlock(&mutex4);
            break;
        }
        if (m==0)
        pthread_mutex_lock(&mutex4);
        m++;
        g=(struct group_node*)malloc(sizeof(group_node_t));
        g->data.gid=s1.rid;
        strcpy(g->data.name,s1.name);
        g->data.power=s1.ret;
         List_AddTail(group1,g); 
        break;
        case 'q':
            if (s1.sid==0)
                {
                    n=0;
                     pthread_mutex_lock(&mutex10);
                     allcansee=1;
                      pthread_mutex_unlock(&mutex10);
                    pthread_mutex_unlock(&mutex5);
                    break;
                }
                    if (n==0)
                    pthread_mutex_lock(&mutex5);
                    n++;
                    old=(yan_node_t*)malloc(sizeof(yan_node_t));
                    old->data.xu=n;
                    old->data.sid=s1.sid;
                    strcpy(old->data.name,s1.name);
                    old->data.type=s1.ret;
    //              printf("%-20d%-20s%-20d\n",s1.rid,s1.name,s1.ret);
                    List_AddTail(gyan,old);                
        break;
        case 'r':
         if (s1.rid==0)
            {
                o=0;
                 pthread_mutex_lock(&mutex10);
                allcansee=1;
                 pthread_mutex_unlock(&mutex10);
                pthread_mutex_unlock(&mutex6);
                break;
            }
                if (o==0)
                {
                List_Free(glist,people_node_t);
                pthread_mutex_lock(&mutex6);
                }
                o++;
                new=(people_node_t*)malloc(sizeof(people_node_t));
                new->data.id=s1.rid;
                strcpy(new->data.name,s1.name);
                new->data.status=s1.ret;
                
  //              printf("%-20d%-20s%-20d\n",s1.rid,s1.name,s1.ret);
                List_AddTail(glist,new);     
        break;
        case 't':
             if (qunliao!=0)
                {
                    if (s1.rid==qunliao)
                    {
                        printf("\n                                    sid:%d\n",s1.sid);
                        printf("                                    %s\n",s1.mes);
                        s1.tye='1';
                        s1.ret=myid;
                        send(cfd,&s1,sizeof(s1),0);
                        break;
                    }
                    else printf("群id:%d有一条新消息\n",s1.rid);
                }
        if (s1.sid==0) //发送者id不可能为0,表示结束并放开锁
            {
                printf("群id:%d有%d条新消息\n",s1.rid,p);
                p=0;
                 pthread_mutex_lock(&mutex10);
                allcansee=1;
                 pthread_mutex_unlock(&mutex10);
                pthread_mutex_unlock(&mutex7);
             
                break;
            }
                if (p==0)
                pthread_mutex_lock(&mutex7);
                p++;
                printf("群id:%d有一条新消息\n",s1.rid);
                nmes=(mes_node_t*)malloc(sizeof(mes_node_t));
                nmes->data.sid=s1.sid;  //发送者
                nmes->data.rid=s1.rid;  //群聊id
                strcpy(nmes->data.mes,s1.mes);           
  //              printf("%-20d%-20s%-20d\n",s1.rid,s1.name,s1.ret);
                List_AddTail(gmes1,nmes);  
        break;
        case 'u':
        if (s1.sid==0) //发送者id不可能为0,表示结束并放开锁
            {
                v=0;
                 pthread_mutex_lock(&mutex10);
                allcansee=1;
                 pthread_mutex_unlock(&mutex10);
                pthread_mutex_unlock(&mutex8);
                break;
            }
                if (v==0)
                pthread_mutex_lock(&mutex8);
                v++;
                lmes=(mes_node_t*)malloc(sizeof(mes_node_t));
                lmes->data.sid=s1.sid;
                strcpy(lmes->data.mes,s1.mes);
                List_AddTail(gmes2,lmes); 
        break;
        case 'v':
             if (s1.sid==0)
            {
                q=0;
                pthread_mutex_unlock(&mutex9);
                 pthread_mutex_lock(&mutex10);
                allcansee=1;
                 pthread_mutex_unlock(&mutex10);
                break;
            }
                if (q==0)
                pthread_mutex_lock(&mutex9);
                q++;
                file1=(file_node_t*)malloc(sizeof(file_node_t));
                file1->data.id=q;
                file1->data.sid=s1.sid;
                strcpy(file1->data.name,s1.name);
                file1->data.status=s1.rid;
                file1->data.size=s1.ret;         
  //              printf("%-20d%-20s%-20d\n",s1.rid,s1.name,s1.ret);
                List_AddTail(flist,file1);     
        break;
        case 'w':
         out=creat(s1.name,0664);
        int len=s1.ret;
        char buf[5000];
        int num;
        while(len>0 ){
            num=recv(cfd,buf,4096,0); 
            len=len-num;
            write(out,buf,num);
        	memset(buf,'\0',sizeof(buf));
        }

        close(out);
        pthread_mutex_lock(&mutex10);
        allcansee=1;
        pthread_mutex_unlock(&mutex10);
        break;
        case 'x':
         pthread_mutex_lock(&mutex10);
            if (s1.ret==0)
            {
                allcansee=0;
            }
            else {
                allcansee=1;
                
                }
                 pthread_mutex_unlock(&mutex10);
        break;
        }
    
    }
}
void exitgroup(int cfd,int gid)
{
    char choice;
    exit1:
    printf("你真的要退出本群聊吗?输入'y'或'n'");
    fflush(stdin);
    while(scanf("%c",&choice)!=1)
    {
        printf("输入的不是一个字符,请重新输入\n");
         while(getchar()!='\n');
         goto exit1;
    }
    while(getchar()!='\n');
    if (choice=='y')
    {
        struct work temp;
        temp.tye='x';
        temp.sid=gid;
        temp.rid=myid;
        send(cfd,&temp,sizeof(temp),0);
        return;
    }
    else if (choice=='n')
    {
        return;
    }
    else {
        printf("输入了一个无效字符,请重新输入\n");
        goto exit1;
    }
    
}
void yanzhengg(int cfd,int gid)
{
    int id;
    yan_node_t *p;
    printf("输入操作的序号\n");
    fflush(stdin);
    if (scanf("%d",&id)!=1)
    {  
        printf("输入不合法,输入回车继续\n");
        while(getchar()!='\n');
        return;
    }
     while(getchar()!='\n');
    List_ForEach(gyan,p)
    {
         struct work temp;
        if (p->data.xu==id)
        {
             printf("%-20s%-20s%-20s%-20s\n","序号","id","用户名","种类");
            printf("%-20d%-20d%-20s",p->data.xu,p->data.sid,p->data.name);
             if (p->data.type==1)
            {
                printf("%-20s\n","申请");
            }
            else if (p->data.type==0)
            {
                printf("%-20s\n","删除");
            }
            char a;
            printf("输入'1'来同意此条申请\n");
            printf("输入'2'来拒绝此条申请\n");
            yanzheng2:
            fflush(stdin);
            printf("your choice:");
            scanf("%c",&a);
            while(getchar()!='\n');
            switch(a)
            {
                case '1':
                temp.tye='t';
                temp.rid=gid;
                temp.sid=p->data.sid;
                temp.ret=p->data.type;
                printf("已发送处理请求\n");
                send(cfd,&temp,sizeof(temp),0);
                break;
                case '2':
                temp.tye='u';
                temp.rid=gid;
                temp.sid=p->data.sid;
                temp.ret=p->data.type;
                printf("已发送处理请求\n");
                send(cfd,&temp,sizeof(temp),0);
                break;
                default:
                printf("不是一个合法选项,请重新输入\n");
                goto yanzheng2;
                break;
            }
            break;
        }
        
    }
    printf("无效的序号,输入回车继续\n");
    while(getchar()!='\n');
    

}
void yanzheng(int cfd)
{
    int id;
    yan_node_t *p;
    printf("输入操作的序号\n");
    fflush(stdin);
    if (scanf("%d",&id)!=1)
    {  
        printf("输入不合法\n");
        return;
    }
     while(getchar()!='\n');
    List_ForEach(list1,p)
    {
         struct work temp;
        if (p->data.xu==id)
        {
             printf("                        %-20s%-20s%-20s%-20s\n","序号","id","用户名","种类");
            printf("                        %-20d%-20d%-20s",p->data.xu,p->data.sid,p->data.name);
             if (p->data.type==1)
            {
                printf("%-20s\n","申请");
            
                char a;
                printf("输入'1'来同意此条申请\n");
                printf("输入'2'来拒绝此条申请\n");
                yanzheng1:
                fflush(stdin);
                printf("your choice:");
                scanf("%c",&a);
                while(getchar()!='\n');
                switch(a)
                {
                    case '1':
                    temp.tye='h';
                    temp.rid=myid;
                    temp.sid=p->data.sid;
                    temp.ret=p->data.type;
                    printf("已发送处理请求\n");
                    send(cfd,&temp,sizeof(temp),0);
                    return;
                    break;
                    case '2':
                    temp.tye='i';
                    temp.rid=myid;
                    temp.sid=p->data.sid;
                    temp.ret=p->data.type;
                    printf("已发送处理请求\n");
                    send(cfd,&temp,sizeof(temp),0);
                    return;
                    break;
                    default:
                    printf("不是一个合法选项,请重新输入\n");
                    goto yanzheng1;
                    break;
                }
            }
             else if (p->data.type==0)
            {
                printf("%-20s\n","删除");
                printf("输入回车已读此条验证消息\n");
                 temp.tye='i';
                    temp.rid=myid;
                    temp.sid=p->data.sid;
                    temp.ret=p->data.type;
                    send(cfd,&temp,sizeof(temp),0);
                    while(getchar()!='\n');
                    return;
            }
            break;
        }
    }
    printf("无效的序号\n");

}
void fetchallfriend(int cfd)
{
     char a;
     int simple=0;
    while(1)
    {
         pthread_mutex_lock(&mutex10);
        allcansee=-1;
         pthread_mutex_unlock(&mutex10);
          List_Free(list,people_node_t);
            struct work temp={'c',0,0,"","",0};
            temp.sid=myid;
            send(cfd,&temp,sizeof(struct work),0);
            while(1)
            {
                 pthread_mutex_lock(&mutex10);
                
                if (allcansee==-1)
                {
                    printf("等待服务器响应\n");
                     pthread_mutex_unlock(&mutex10);
                     sleep(1);
                }
                else {allcansee=-1;
                   pthread_mutex_unlock(&mutex10);
                    break;
                   }
            }
        pthread_mutex_lock(&mutex);
          system("clear");
        people_node_t *p;
        printf("============================ 好友列表 ============================\n");
        printf("                 %-20s%-20s%-20s\n","id","用户名","在线状态");
        List_ForEach(list,p)
        {
            printf("                 %-20d%-20s",p->data.id,p->data.name);
            if (p->data.status==1)
            printf("%-20s","在线");
            else printf("%-20s","不在线");
            printf("\n");
        }
        pthread_mutex_unlock(&mutex);
       
        printf("输入'1'来退出查看\n");
        getfriend1:
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            simple=1;
            break;
            default:
            printf("不是一个合法选项,请重新输入\n");
           goto getfriend1;
            break;
        }
        if (simple==1)
        break;
    }
    
}
void add_friend(int cfd)
{    pthread_mutex_lock(&mutex10);       
     allcansee=-1;
      pthread_mutex_unlock(&mutex10);
            int id;
            printf("请输入你想添加的id号\n");
            fflush(stdin);
            if(scanf("%d",&id)!=1)
            {
                printf("输入的不是一个数字!\n");
               
            }
            while(getchar()!='\n');
            if (ismyfriend(id))
            {
                printf("id:%d用户已经是您的好友!\n",id);
                return;
            }
            if (id==myid)
            {
                printf("不能加自己为好友!\n");
                return;
            }
            struct work ss;
            ss.tye='d';
            ss.rid=id;
            ss.sid=myid;
            int i=0;
            send(cfd,&ss,sizeof(ss),0);
           while(1)
           {
                pthread_mutex_lock(&mutex10);
                if (allcansee==-1)
                {
                    printf("等待客户端响应\n");
                    i++;
                     pthread_mutex_unlock(&mutex10);
                    if (i==5)
                    send(cfd,&ss,sizeof(ss),0);
                    sleep(1);
                }
                else {
                 pthread_mutex_unlock(&mutex10);
                 break;
                 }
           }
         
             pthread_mutex_lock(&mutex10);
             
            if (allcansee==1)
            {struct work dd=ss;
                dd.ret=1;
                printf("id:%d 用户存在,已发出请求\n",id);
                dd.tye='f';
                send(cfd,&dd,sizeof(ss),0);
                sleep(1);
            }
            else if(allcansee==0)
            {
                printf("id:%d 用户不存在\n",id);
                 sleep(1);
            }
             pthread_mutex_unlock(&mutex10);
        

   
}
void delete_friend(int cfd)
{
    int id;
    printf("请输入你想删除好友的id号\n");
    fflush(stdin);
    if(scanf("%d",&id)!=1)
    {
        printf("输入的不是一个数字!\n");
        return;
    }
    while(getchar()!='\n');
    if (!ismyfriend(id))
    {
        printf("该用户不是您的好友!\n");
        return;
    }
    struct work ss;
    ss.tye='j';
    ss.rid=id;
    ss.sid=myid;
    ss.ret=0;
    people_node_t *p,*ps;
    pthread_mutex_lock(&mutex);
    List_ForEach(list,p)
    {
        if(p->data.id==ss.rid)
        {
            break;
        }
    }
    ps=p;
    (p->prev)->next=p->next;
    List_FreeNode(p);
        pthread_mutex_unlock(&mutex);
    send(cfd,&ss,sizeof(ss),0);
}
int ismyfriend(int id)
{
    people_node_t*p;
    List_ForEach(list,p)
    {
        if (p->data.id==id)
        return 1;

    }
    return 0;
}
int ismygroup(int gid)
{
     group_node_t*p;
    List_ForEach(group1,p)
    {
        if (p->data.gid==gid)
        return 1;

    }
    return 0;
}
char *getname(int id) 
{
    people_node_t*p;
    List_ForEach(list,p)
    {
        if (p->data.id==id)
        return p->data.name;

    }
    printf("error\n");
    return NULL;
}
char *getgname(int id) 
{
    group_node_t*p;
    List_ForEach(group1,p)
    {
        if (p->data.gid==id)
        return p->data.name;

    }
    printf("error\n");
    return NULL;
}
int isonline(int id) 
{
    people_node_t*p;
    List_ForEach(list,p)
    {
        if (p->data.id==id)
        {
            if (p->data.status==1)
            {
                return 1;
            }
            return 0;
        }

    }
}
void getrequst(int cfd)
{
    char a;
    int simple=0;
    while(1)
    {
         pthread_mutex_lock(&mutex10);
        allcansee=-1;
        pthread_mutex_unlock(&mutex10);
        List_Free(list1,yan_node_t);
        struct work temp={'g',0,0,"","",0};
        temp.sid=myid;
        send(cfd,&temp,sizeof(struct work),0);
            while(1)
            {   pthread_mutex_lock(&mutex10);
                if (allcansee==-1)
                {
                    printf("I'm waiting for data now\n");
                        pthread_mutex_unlock(&mutex10);
                    sleep(1);
                    system("clear");
                }
                else {
                    pthread_mutex_unlock(&mutex10);
                    break;
                }
            }
        system("clear");
        printf("============================ 好友管理 ============================\n");
        pthread_mutex_lock(&mutex1);
        yan_node_t *p;
        printf("                        %-20s%-20s%-20s%-20s\n","序号","id","用户名","种类");
        List_ForEach(list1,p)
        {
            printf("                        %-20d%-20d%-20s",p->data.xu,p->data.sid,p->data.name);
            if (p->data.type==1)
            {
                printf("%-20s\n","申请");
            }
            else if (p->data.type==0)
            {
                printf("%-20s\n","删除");
            }
        }
        pthread_mutex_unlock(&mutex1);
       
        printf("输入'1'来选择一条信息操作\n");
        printf("输入'2'来退出\n");
        getrequst1:
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
          
            case '1':
            yanzheng(cfd);
            break;
            case '2':
            simple=1;
            break;
            default:
            printf("不是一个合法选项,请重新输入\n");
           goto getrequst1;
            break;
        }
        if (simple==1)
        break;
        printf("输入回车来继续\n");
        while(getchar()!='\n');
    }
}
int logon(struct work temp,int cfd)
{
    struct work s1;
    temp.tye='b';
    send(cfd,&temp,sizeof(temp),0);
    recv(cfd,&s1,sizeof(s1),0);
    printf("ret :%d",s1.ret);
    if (s1.ret==0)
    return 0;
    else if (s1.ret==1)
    return 1;
}
int login(struct work temp,int cfd)
{
    struct work s1;
    temp.tye='s';
    send(cfd,&temp,sizeof(temp),0);
    recv(cfd,&s1,sizeof(s1),0);
    printf("ret :%d",s1.ret);
    if (s1.ret==0)
    return 0;
    else if (s1.ret==1)
    {
    myid=s1.sid;
    return 1;
    }
    else if (s1.ret==-1)
    return -1;
}
void creategroup(int cfd)
{
    printf("请为您想创建的群组设置一个名字\n");
    struct work test;
    int j;
    char n;
    char usrname[30];
     add_group:
        printf("群组名:");
        j = 0;
        while ((n = getchar()) != '\n')
        {
            if (n == ' ' || j >= 29)
            {
                while ((n = getchar()) != '\n');
                
                printf("群组名不合规\n");
                j = 0;
                goto add_group;
            }
            usrname[j++] = n;
        }
        if (n == '\n' && j == 0)
        {
            printf("群组名不为空\n");
            j = 0;
            goto add_group;
        }
        usrname[j] = '\0';
    strcpy(test.name,usrname);
    test.tye='o';
    test.sid=myid;
     pthread_mutex_lock(&mutex10);
     allcansee=-1;
      pthread_mutex_unlock(&mutex10);
    send(cfd,&test,sizeof(test),0);
    int i=0;
    while(1)
    {
          pthread_mutex_lock(&mutex10);
        if(allcansee==-1)
        {
              pthread_mutex_unlock(&mutex10);
            printf("等待服务器响应\n");
            sleep(1);
            i++;
            if (i==5)
            send(cfd,&test,sizeof(test),0);
        }
        else{
            break;
        }
    }
    if (allcansee==0)
    {
        printf("该群组已经存在!\n");
    }
    else printf("已成功建立群组\n");
     allcansee=-1;
      pthread_mutex_unlock(&mutex10);
    printf("输入回车来返回上层界面\n");
    while(getchar()!='\n');
}
int SysLogin(int efd)  // SL界面
{
   
    struct work test={'a',0,0,"","",0};
    int i = 0;
    int j = 0;
    char n;
    char c;
    char usrname[30];
    char password[30];
    while (i <= 3)
    {
        add_usr:
        system("clear");
        printf("============================ 登陆界面 ============================\n");
   
        printf("                      用户名:");
        j = 0;
        while ((n = getchar()) != '\n')
        {
            if (n == ' ' || j >= 29)
            {
                while ((n = getchar()) != '\n');
                
                printf("用户名不合规,请在回车后继续\n");
                while(getchar()!='\n');
                j = 0;
                
                goto add_usr;
            }
            usrname[j++] = n;
        }
        if (n == '\n' && j == 0)
        {
            printf("用户名不为空\n");
            j = 0;
            goto add_usr;
        }
        usrname[j] = '\0';

    add_pass_1:
        printf("                      密码:");
        j = 0;
        while ((n = getch()) != '\n')
        {
            printf("*");
            if (n == ' ' || j >= 29)
            {
                while ((n = getch()) != '\n')
                    ;
                printf("\n密码不合规\n");
                j = 0;
                goto add_pass_1;
            }
            password[j++] = n;
        }
        if (n == '\n' && j == 0)
        {
            printf("\n密码不为空\n");
            j = 0;
            goto add_pass_1;
        }
        password[j] = '\0';
        i++;
        printf("\n");
        strcpy(test.name,usrname);
        strcpy(test.password,password);
        int ccc;
        if ((ccc=login(test,efd))==0)
        {
            printf("用户不存在或密码错误\n");
            printf("输入'0'来返回上层界面或'1'来继续尝试登陆\n");
            syc:
            fflush(stdin);
            printf("you choice:");
            scanf("%c",&c);
            getchar();
            if (c=='0')
            {
                return 0;
            }
            else if (c=='1')
           {}
           else {
               printf("%c不是一个合法选项请重新输入\n",c);
               goto syc;
           }
            if (i == 3)
            {
                printf("错误次数过多\n");
                return 0;
            }
        }
        else if (ccc==-1)
        {
            printf("该用户已经登陆!\n");
            return 0;
        }
        else
        {
            printf("Welcome!id:%d %s\n", myid,usrname);
            break;
        }
    }
        return 1;
}
int SysLogon(int efd)
{
        struct work test={'b',0,0,"","",0};
    int j = 0;
    char n;
    char c;
    char usrname[30];
    char password[30];
    while (1)
    {
         add_usr:
         system("clear");
        printf("============================ 注册界面 ============================\n");

        printf("                      用户名:");
        j = 0;
        while ((n = getchar()) != '\n')
        {
            if (n == ' ' || j >= 29)
            {
                while ((n = getchar()) != '\n');
                
                printf("用户名不合规,请在回车后继续\n");
                while(getchar()!='\n');
                j = 0;
                goto add_usr;
            }
            usrname[j++] = n;
        }
        if (n == '\n' && j == 0)
        {
            printf("用户名不为空\n");
            j = 0;
            goto add_usr;
        }
        usrname[j] = '\0';

    add_pass_1:
        printf("                      密码:");
        j = 0;
        while ((n = getch()) != '\n')
        {
            printf("*");
            if (n == ' ' || j >= 29)
            {
                while ((n = getch()) != '\n')
                    ;
                printf("\n密码不合规\n");
                j = 0;
                goto add_pass_1;
            }
            password[j++] = n;
        }
        if (n == '\n' && j == 0)
        {
            printf("\n密码不为空\n");
            j = 0;
            goto add_pass_1;
        }
        password[j] = '\0';
        printf("\n");
        strcpy(test.name,usrname);
        strcpy(test.password,password);
        if (logon(test,efd) == 0)
        {
            printf("用户已存在或密码错误\n");
            printf("输入'0'来返回上层界面或'1'来继续尝试注册\n");
            syc:
            fflush(stdin);
            printf("you choice:");
            scanf("%c",&c);
            getchar();
            if (c=='0')
            {
                return 0;
            }
            else if (c=='1')
           {}
           else {
               printf("%c不是一个合法选项请重新输入\n",c);
               goto syc;
           }
        }
        else
        {
            printf("注册成功,请返回主页面登陆\n");
            break;
        }
    }
        return 1;
}
void readsmes(int cfd)
{
   char *a;
   int id;
   char n;
     people_node_t *p;
    mes_node_t *q;
    int i=0;
   readsmes1:
   system("clear");
        printf("============================ 聊天记录 ============================\n");
        printf("                        %-20s%-20s%-20s\n","id","用户名","消息数");
        
        List_ForEach(list,p)
        {
            i=0;
            List_ForEach(mes2,q)
            {
                if ((q->data.sid==p->data.id)||(q->data.rid==p->data.id))
                i++;
            }
            printf("                        %-20d%-20s%-20d\n",p->data.id,p->data.name,i);
        }
    printf("请选择你要读取的用户(id)\n");
    fflush(stdin);
    while(scanf("%d",&id)!=1)
    {
        printf("输入的不是一个数字\n");
        while(getchar()!='\n');
    }
    while (getchar()!='\n');
    if (!ismyfriend(id))
    {
        printf("id:%d用户不是您的好友,输入回车继续\n",id);
        while(getchar()!='\n');
        return;
    }
    List_ForEach(mes2,q)
    {
        if (q->data.sid==id)
        {
            printf("                                                id:%d\n",id);
            printf("                                                %s",q->data.mes);
        }
        else if (q->data.rid==id)
        {
            printf("您发出:\n");
            printf("%s",q->data.mes);
        }
    }
    printf("\n");
    printf("输入'1'继续查询\n");
    printf("输入'2'退出查询\n");
     readsmes2:
    fflush(stdin);
    n=getchar();
    while (getchar()!='\n');
    switch(n)
    {
        case '1':
          goto readsmes1;
        break;
        case '2':
        break;
        default:
        printf("输入不合法,请重新输入\n");
        goto  readsmes2;
        break;
    }
    
} 
void readgmes(int cfd,int gid)
{
   mes_node_t *q;
    pthread_mutex_lock(&mutex10);
   allcansee=-1;
    pthread_mutex_unlock(&mutex10);
   char *a;
   system("clear");
    struct work temp;
     List_Free(gmes2,mes_node_t);
    temp.tye='2';temp.sid=myid;temp.rid=gid;
     send(cfd,&temp,sizeof(temp),0);
   while(1)
   {
        pthread_mutex_lock(&mutex10);
        if(allcansee==-1)
        {
             pthread_mutex_unlock(&mutex10);
            printf("等待服务器响应\n");
            sleep(1);
            system("clear");
        }
        else{
         pthread_mutex_unlock(&mutex10);
        break;
        }
   }
    a=getgname(gid);
    printf("群组id:%d 群组名:%s\n",gid,a);
    pthread_mutex_lock(&mutex8);
    List_ForEach(gmes2,q)
    {
            if (q->data.sid==myid)
            {
            printf("id: %d\n",q->data.sid);
            printf("%s",q->data.mes);
            }
            else {
            printf("                                    id: %d\n",q->data.sid);
            printf("                                    %s",q->data.mes);
            }

    }
    pthread_mutex_unlock(&mutex8);
    printf("输入回车键返回上层界面\n");
    while(getchar()!='\n');
    
}  
void nreadsmes(int cfd)
{
    people_node_t *p;
    mes_node_t *q;
    int i=0;
    int id;
    char a;
    mesid2:
    system("clear");
    struct work test;
    test.tye='l';
    test.rid=myid;
    mes_node_t* trans;
    system("clear");
    printf("============================ 聊天记录 ============================\n");
    printf("                        %-20s%-20s%-20s\n","id","用户名","消息数");
    List_ForEach(list,p)
    {
        i=0;
        List_ForEach(mes1,q)
        {
            if (q->data.sid==p->data.id)
            i++;
        }
        printf("                        %-20d%-20s%-20d\n",p->data.id,p->data.name,i);
    }
    printf("请选择你要读取的用户(id)\n");
    mesid:
    fflush(stdin);
    printf("yourchoice:");
    if (scanf("%d",&id)!=1)
    {  
        printf("输入不合法\n");
        while(getchar()!='\n');
        goto mesid;
    }
     while(getchar()!='\n');
     if (!ismyfriend(id))
     {
         printf("id:%d的用户不是您的好友\n",id);
     }
      List_ForEach(mes1,q)
        {
            if (q->data.sid==id)
            {
                trans=q->prev;
                test.sid=q->data.sid;
                strcpy(test.mes,q->data.mes);
                send(cfd,&test,sizeof(test),0);
                 List_DelNode(q);
                List_AddTail(mes2,q);
                printf("id:%d 用户名:%s\n%s",id,getname(id),q->data.mes);
                q=trans;
            }
            
        }
        printf("输入'1'来继续查看\n");
        printf("输入'2'来退出查看\n");
          mesid1:
        fflush(stdin);
        printf("yourchoice:");
        if (scanf("%c",&a)!=1)
        {  
            printf("输入不合法\n");
            while(getchar()!='\n');
            goto mesid1;
        }
         while(getchar()!='\n');
        switch(a)
        {
            case'1':
            goto mesid2;
            break;
            case'2':
            break;
            default:
            printf("不是一个合法选项\n");
            sleep(1);
             goto mesid2;
        }

}
void nreadgmes(int cfd,int gid)
{
     pthread_mutex_lock(&mutex10);
    allcansee=-1;
     pthread_mutex_unlock(&mutex10);
    group_node_t *p;
    mes_node_t *q;
    int i=0;
    List_Free(gmes1,mes_node_t);
     struct work temp;
        temp.sid=myid;temp.rid=gid;
        int time=0;
        temp.tye='3';send(cfd,&temp,sizeof(temp),0);
        while(1){
                 pthread_mutex_lock(&mutex10);
                if(allcansee==-1)
                    {
                         pthread_mutex_unlock(&mutex10);
                        printf("等待服务器响应\n");
                        sleep(1);
                        system("clear");
                    }
                    else {
                         pthread_mutex_unlock(&mutex10);
                         break;
                    }
        }
    system("clear");
    struct work test;
     test.tye='1';
      test.ret=myid;
/*    printf("%-20s%-20s%-20s\n","gid","群组名","消息数");
    List_ForEach(group1,p)
    {
        i=0;
        pthread_mutex_lock(&mutex7);
        List_ForEach(gmes1,q)
        {
            if (q->data.sid==p->data.gid)
            i++;
        }
        pthread_mutex_unlock(&mutex7);
        printf("%-20d%-20s%-20d\n",p->data.gid,getgname(p->data.gid),i);
    }
   */ 
      List_ForEach(gmes1,q)
        {
            if (q->data.rid==gid)
            {
                test.sid=q->data.sid;
                test.rid=q->data.rid;
                strcpy(test.mes,q->data.mes);
                send(cfd,&test,sizeof(test),0);
                printf("id:%d:\n %s",q->data.sid,q->data.mes);
            }
        }
        printf("输入回车返回上层界面\n");
        while(getchar()!='\n');

}
void fetchallmes(int cfd)
{
    int simple=0;
     char a;
    while(1)
    {
         system("clear");
        printf("============================ 欢迎使用聊天室 ============================\n");
        printf("                        输入'1'来查看未读消息\n");
        printf("                        输入'2'来查看已读消息\n");
        printf("                        输入'3'来退出消息记录\n");
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            nreadsmes(cfd);
            break;
            case '2':
            readsmes(cfd);
            break;
            case '3':
            simple=1;
            break;
            default:
            printf("不是一个合法选项请重新输入\n");
            break;
        }
        if (simple==1)
            break;
    }
}
void chatwithf(int cfd)
{
    int id;
    printf("请输入你想私聊好友的id号\n");
    fflush(stdin);
    if(scanf("%d",&id)!=1)
    {
        printf("输入的不是一个数字!\n");
        printf("输入回车键继续\n");
         while(getchar()!='\n');
        return;
    }
     pthread_mutex_lock(&mutex10);
        allcansee=-1;
    pthread_mutex_unlock(&mutex10);
          List_Free(list,people_node_t);
            struct work temp={'c',0,0,"","",0};
            temp.sid=myid;
            send(cfd,&temp,sizeof(struct work),0);
            while(1)
            {
                 pthread_mutex_lock(&mutex10);
                
                if (allcansee==-1)
                {
                    printf("等待服务器响应\n");
                     pthread_mutex_unlock(&mutex10);
                     sleep(1);
                }
                else {allcansee=-1;
                   pthread_mutex_unlock(&mutex10);
                    break;
                   }
            }
    while(getchar()!='\n');
    if (!ismyfriend(id))
    {
        printf("该用户不是您的好友!\n");
         printf("输入回车键继续\n");
          while(getchar()!='\n');
        return;
    }
    char *name=getname(id);
    struct work mes;
    mes_node_t*nmes;
    siliao=id;
    system("clear");
    mes.rid=id;mes.sid=myid;mes.tye='k';mes.ret=0; //k为发送消息包,并通过ret=1代表此消息对方未读.
    printf("                        %s正在与你私聊,输入\"/exit来退出\"\n",name);
    if (!isonline(id))
    {
        printf("当前对方不在线\n");
    }
    else printf("当前用户在线\n");
     printf("your send: ");
    while(fgets(mes.mes,1000,stdin))
    {
 //       printf("your send:\n");
        if (strcmp(mes.mes,"/exit\n")==0)
        {
            break;
        }
          nmes=(mes_node_t*)malloc(sizeof(mes_node_t));
                nmes->data.sid=myid;
                nmes->data.rid=id;
                strcpy(nmes->data.mes,mes.mes);  
                List_AddTail(mes2,nmes);
        send(cfd,&mes,sizeof(struct work),0);
    }
    siliao=0;
}
void chatwithg(int cfd)
{
    struct work test;
    group_node_t* p;
    pthread_mutex_lock(&mutex10);
    allcansee=-1;
    pthread_mutex_unlock(&mutex10);
    system("clear");
    List_Free(group1,group_node_t);
    test.tye='q';
    test.sid=myid;
    send(cfd,&test,sizeof(test),0);
    while(1)
    {
            pthread_mutex_lock(&mutex10);
        if (allcansee==-1)
        {
                pthread_mutex_unlock(&mutex10);
            printf("等待服务器响应\n");
            sleep(1);
        }
        else {
                pthread_mutex_unlock(&mutex10);
            break;
            }
            
    }
    pthread_mutex_lock(&mutex4);
    printf("%-20s%-20s\n","群组id","群组名称");
    List_ForEach(group1,p)
    {
        printf("%-20d%-20s\n",p->data.gid,p->data.name);
    }
    pthread_mutex_unlock(&mutex4);
    int gid;
    printf("请输入你想进入的群组id号\n");
    fflush(stdin);
    if(scanf("%d",&gid)!=1)
    {
        printf("输入的不是一个数字!\n");
        return;
    }
    while(getchar()!='\n');
    if (!ismygroup(gid))
    {
        printf("您还未加入该群组!,输入回车键继续\n");
        while(getchar()!='\n');
        return;
    }
    char *name=getgname(gid);
    struct work mes;
    qunliao=gid;
    mes.rid=gid;mes.sid=myid;mes.tye='z';mes.ret=0; //k为发送消息包,并通过ret=0代表此消息对方未读.
    printf("你正在群聊id:%d %s中,输入exit来退出\n",gid,name);
    while(fgets(mes.mes,1000,stdin))
    {
        printf("your send:\n");
        if (strcmp(mes.mes,"exit\n")==0)
        {
            break;
        }
        send(cfd,&mes,sizeof(mes),0);
    }
    qunliao=0;
}
void fetchallgmes(int cfd,int gid)
{
    int simple=0;
    char a;
    while(1)
    {   
        system("clear");
        printf("输入'1'来查看未读消息\n");
        printf("输入'2'来查看已读消息\n");
        printf("输入'3'来退出消息记录\n");
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            nreadgmes(cfd,gid);
            break;
            case '2':
            readgmes(cfd,gid);
            break;
            case '3':
            simple=1;
            break;
            default:
            printf("不是一个合法选项请重新输入\n");
            break;
        }
        if (simple==1)
            break;
    }
}
void joingroup(int cfd)
{
    struct work test;
        pthread_mutex_lock(&mutex10);
        allcansee=-1;
        pthread_mutex_unlock(&mutex10);
        system("clear");
        List_Free(group1,group_node_t);
        test.tye='q';
        test.sid=myid;
        send(cfd,&test,sizeof(test),0);
        while(1)
        {
                pthread_mutex_lock(&mutex10);
            if (allcansee==-1)
            {
                    pthread_mutex_unlock(&mutex10);
                printf("等待服务器响应\n");
                sleep(1);
            }
            else {
                    pthread_mutex_unlock(&mutex10);
                break;
                }
                
        }
    int id;
    struct work temp;
    printf("请输入您想加入的群组id号\n");
    fflush(stdin);
    while (scanf("%d",&id)!=1)
    {   while(getchar()!='\n');
        printf("输入的不是一个数字!,请重新输入\n");
    }
    while(getchar()!='\n');
    if (ismygroup(id))
    {
        printf("你已经是id:%d的群组成员,输入回车继续",id);
        while(getchar()!='\n');
        return;
    }
    temp.sid=myid;
    temp.rid=id;
    temp.tye='p';
    send(cfd,&temp,sizeof(temp),0);
      pthread_mutex_lock(&mutex10);
      allcansee=-1;
       pthread_mutex_unlock(&mutex10);
    while(1)
    {  pthread_mutex_lock(&mutex10);
         if(allcansee==-1)
            {
                 pthread_mutex_unlock(&mutex10);
                sleep(1);
            }
            else break;
    }
    if (allcansee==0)
    {
        printf("该群组不存在!\n");
    }
    else if (allcansee==1)
    {
        printf("已成功发出请求\n");
    }
    pthread_mutex_unlock(&mutex10);
    printf("按下回车键返回上层界面\n");
    while(getchar()!='\n');
}
void getgroup(int cfd)
{
    struct group_node* p;
    char a; struct work test;
    int simple=0;
    while(1)
    {
        pthread_mutex_lock(&mutex10);
        allcansee=-1;
        pthread_mutex_unlock(&mutex10);
        system("clear");
        List_Free(group1,group_node_t);
        test.tye='q';
        test.sid=myid;
        send(cfd,&test,sizeof(test),0);
        while(1)
        {
                pthread_mutex_lock(&mutex10);
            if (allcansee==-1)
            {
                    pthread_mutex_unlock(&mutex10);
                printf("等待服务器响应\n");
                sleep(1);
            }
            else {
                    pthread_mutex_unlock(&mutex10);
                break;
                }
                
        }
        pthread_mutex_lock(&mutex4);
        printf("%-20s%-20s\n","群组id","群组名称");
        List_ForEach(group1,p)
        {
            printf("%-20d%-20s\n",p->data.gid,p->data.name);
        }
        pthread_mutex_unlock(&mutex4);
        printf("输入'1'来返回上层界面\n");
        fflush(stdin);
        while(scanf("%c",&a)!=1)
        {
            printf("输入的不是一个有效选项\n");
            while(getchar()!='\n');
        }
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            simple=1;
            break;
            default:
            printf("输入的不是有效选项,请重新输入\n");
            break;
        }
        if (simple==1)
        {
            break;
        }
    }
}
void deletemate(int gid,int cfd)
{
        char a;
     int simple=0;
     int id;
     int find=0;
    while(1)
    {
        system("clear");
        pthread_mutex_lock(&mutex6);
        people_node_t *p;
        printf("%-20s%-20s\n","id","用户名");
        List_ForEach(glist,p)
        {
            if (p->data.status==0)
            printf("%-20d%-20s\n",p->data.id,p->data.name);         
        }
        pthread_mutex_unlock(&mutex6);
       
  //      printf("输入'1'来刷新状态\n");
        printf("输入'1'来选择一个群成员(id)\n");
        printf("输入'2'来退出查看\n");
        deletemate1:
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            printf("id:");
            fflush(stdin);
            while(scanf("%d",&id)!=1)
            {
                printf("输入的不是一个数字!请重新输入\n");
                while(getchar()!='\n');
            }
            while(getchar()!='\n');
             pthread_mutex_lock(&mutex6);
             find=0;
            List_ForEach(glist,p)
            {
                if (p->data.id==id)
                {
                    find=1;
                    if (p->data.status>1)
                    {
                        printf("该用户是群主或管理员,不能删除!\n");
                    }
                    else{
                         struct work temp={'x',0,0,"","",0};
                         temp.sid=gid;
                         temp.rid=id;
                         send(cfd,&temp,sizeof(temp),0);
                    }
                    break;
                }    
            }
            pthread_mutex_unlock(&mutex6);
            if (find==0)
            printf("该用户不是群成员!\n");
            printf("输入回车继续\n");
            while(getchar()!='\n');
            simple=1;
            break;
            case '2':
            simple=1;
            break;
            default:
            printf("不是一个合法选项,请重新输入\n");
           goto deletemate1;
            break;
        }
        if (simple==1)
        break;
    }
}
void setadmin(int gid,int cfd)
{
     char a;
     int simple=0;
     int id;
     int find=0;
    while(1)
    {
        system("clear");
        pthread_mutex_lock(&mutex6);
        people_node_t *p;
        printf("%-20s%-20s\n","id","用户名");
        List_ForEach(glist,p)
        {
            if (p->data.status==0)
            printf("%-20d%-20s\n",p->data.id,p->data.name);         
        }
        pthread_mutex_unlock(&mutex6);
       
  //      printf("输入'1'来刷新状态\n");
        printf("输入'1'来选择一个群成员(id)\n");
        printf("输入'2'来退出查看\n");
        setadmin1:
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            printf("id:");
            fflush(stdin);
            while(scanf("%d",&id)!=1)
            {
                printf("输入的不是一个数字!请重新输入\n");
                while(getchar()!='\n');
            }
            while(getchar()!='\n');
             pthread_mutex_lock(&mutex6);
             find=0;
            List_ForEach(glist,p)
            {
                if (p->data.id==id)
                {
                    find=1;
                    if (p->data.status>0)
                    {
                        printf("该用户已经是群主或管理员!\n");
                    }
                    else{
                         struct work temp={'w',0,0,"","",0};
                         temp.sid=gid;
                         temp.rid=id;
                         send(cfd,&temp,sizeof(temp),0);
                    }
                    break;
                }    
            }
            pthread_mutex_unlock(&mutex6);
            if (find==0)
            printf("该用户不是群成员!\n");
            printf("输入回车继续\n");
            while(getchar()!='\n');
            simple=1;
            break;
            case '2':
            simple=1;
            break;
            default:
            printf("不是一个合法选项,请重新输入\n");
            printf("输入回车继续\n");
              while(getchar()!='\n');
           goto setadmin1;
            break;
        }
        if (simple==1)
        break;
    }
}
void managegroup(int cfd)
{
    struct group_node *p;
    int id;
    mangroup:
    system("clear");
    printf("============================ 群组管理 ============================\n");
    int i=0;
    printf("                  %-20s%-20s\n","群组id","群组名称");
    pthread_mutex_lock(&mutex4);
    List_ForEach(group1,p)
    {
        printf("                  %-20d%-20s\n",p->data.gid,p->data.name);
    }
    pthread_mutex_unlock(&mutex4);
    printf("请输入你要管理的群组id:\n");
    fflush(stdin);
    while(scanf("%d",&id)!=1)
    {
        printf("输入的不是一个数字!请重新输入\n");
        while(getchar()!='\n');
    }
    while(getchar()!='\n');
    List_ForEach(group1,p)
    {
       if (p->data.gid==id)
       {
           i=1;
           break;
       }
    }
    if (i==0)
    {
        printf("输入的不是有效的id!按回车继续\n");
         while(getchar()!='\n');
        return;
    }
    if (p->data.power==2)
    {
            owner(p,cfd);
    }
    else if (p->data.power==1)
    {
            admin(p,cfd);
    }
    else if (p->data.power==0)
    {
            dog(p,cfd);
    }

}
void getgrequst(group_node_t* temp,int cfd)   //未完成
{
    char a;
    int simple=0;
    while(1)
    {
        pthread_mutex_lock(&mutex10);
        allcansee=-1;
        pthread_mutex_unlock(&mutex10);
            List_Free(gyan,yan_node_t);
            struct work temp1={'r',0,0,"","",0};
            temp1.sid=myid;
            temp1.rid=temp->data.gid;
            send(cfd,&temp1,sizeof(struct work),0);
                while(1)
                {   pthread_mutex_lock(&mutex10);
                    if (allcansee==-1)
                    {
                        printf("I'm waiting for data now\n");
                           pthread_mutex_unlock(&mutex10);
                        sleep(1);
                        system("clear");
                    }
                    else {
                        pthread_mutex_unlock(&mutex10);
                        break;
                    }
                }
        system("clear");
          printf("============================ 群组管理 ============================\n");
        pthread_mutex_lock(&mutex5);
        yan_node_t *p;
        printf("                    %-20s%-20s%-20s%-20s\n","序号","id","用户名","种类");
        List_ForEach(gyan,p)
        {
        printf("                    %-20d%-20d%-20s",p->data.xu,p->data.sid,p->data.name);
            if (p->data.type==1)
            {
                printf("%-20s\n","申请");
            }
            else if (p->data.type==0)
            {
                printf("%-20s\n","删除");
            }
        }
        pthread_mutex_unlock(&mutex5);
       
     //   printf("                        输入'1'来刷新验证消息表\n");
        printf("                        输入'1'来选择一条信息操作\n");
        printf("                        输入'2'来退出\n");
        getgrequst1:
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            yanzhengg(cfd,temp->data.gid);
            break;
            case '2':
            simple=1;
            break;
            default:
            printf("不是一个合法选项,请重新输入\n");
           goto getgrequst1;
            break;
        }
        if (simple==1)
        break;
    }
}
void owner(group_node_t* temp,int cfd) //主人
{
    int simple=0;
    struct work temp2;
    temp2.tye='y';
    temp2.sid=temp->data.gid;
    while(1)
    {
        
        pthread_mutex_lock(&mutex10);
         allcansee=-1;
         pthread_mutex_unlock(&mutex10);
        List_Free(glist,people_node_t);
        struct work temp1={'v',0,0,"","",0};
        int time=0;
        temp1.sid=temp->data.gid;
        send(cfd,&temp1,sizeof(struct work),0);
        while(1)
        {
            pthread_mutex_lock(&mutex10);
            if(allcansee==-1)
            {
                pthread_mutex_unlock(&mutex10);
                time++;
                if(time%5==0)
                {
                    send(cfd,&temp1,sizeof(struct work),0);
                }
                printf("等待服务器响应\n");
                sleep(1);
                system("clear");
            }
            else{
                pthread_mutex_unlock(&mutex10);
                break;
            }
        }



        own:
        system("clear");
          printf("============================ 群组管理 ============================\n");
        char a;
        printf("欢迎你%-20s的群主\n",temp->data.name);
        printf("                        输入'1'来查看群验证信息\n");
        printf("                        输入'2'来设置一个管理员\n");
        printf("                        输入'3'来踢出一个群成员\n");
        printf("                        输入'4'来解散本群组\n");
        printf("                        输入'5'来查看群成员\n");
        printf("                        输入'6'来退出本界面\n");
        fflush(stdin);
        if (scanf("%c",&a)!=1)
        {
            printf("输入不合法,请重新输入\n");
            while(getchar()!='\n');
            goto own;
        }
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            getgrequst(temp,cfd);
            break;
            case '2':
            setadmin(temp->data.gid,cfd);
            break;
            case '3':
            deletemate(temp->data.gid,cfd);
            break;
            case '4':
            send(cfd,&temp2,sizeof(temp1),0);
            simple=1;
            break;
            case '5':
            getgroupmates(temp->data.gid,cfd);
            break;
            case '6':
            simple=1;
            break;
            default:
            printf("输入不合法,请重新输入\n");
            goto own;
            break;
        }
        if (simple==1)
        break;
    }
}
void admin(group_node_t* temp,int cfd)  //管理员
{
     int simple=0;
    while(1)
    {
          pthread_mutex_lock(&mutex10);
         allcansee=-1;
         pthread_mutex_unlock(&mutex10);
        List_Free(glist,people_node_t);
        struct work temp1={'v',0,0,"","",0};
        temp1.sid=temp->data.gid;
        int time=0;
        send(cfd,&temp1,sizeof(struct work),0);
        while(1)
        {
            pthread_mutex_lock(&mutex10);
            if(allcansee==-1)
            {
                pthread_mutex_unlock(&mutex10);
                printf("等待服务器响应\n");
                 time++;
                if(time%5==0)
                {
                    send(cfd,&temp1,sizeof(struct work),0);
                }
                sleep(1);
                system("clear");
            }
            else{
                pthread_mutex_unlock(&mutex10);
                break;
            }
        }

       admin1:
        system("clear");
        printf("============================ 群组管理 ============================\n");
        char a;
        printf("欢迎你%-20s的管理员\n",temp->data.name);
        printf("                        输入'1'来查看群验证信息\n");
        printf("                        输入'2'来踢出一个群成员\n");
        printf("                        输入'3'来查看群成员\n");
        printf("                        输入'4'来退出本群聊\n");
        printf("                        输入'5'来退出本界面\n");
        fflush(stdin);
        if (scanf("%c",&a)!=1)
        {
            printf("输入不合法,请重新输入\n");
            while(getchar()!='\n');
            goto admin1;
        }
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            getgrequst(temp,cfd);
            break;
            case '2':
            deletemate(temp->data.gid,cfd);
            break;
            case '3':
            getgroupmates(temp->data.gid,cfd);
            break;
            case '4':
            exitgroup(cfd,temp->data.gid);
            break;
            case '5':
            simple=1;
            break;
            default:
            printf("输入不合法,请重新输入\n");
            goto admin1;
            break;
        }
        if (simple==1)
        break;
    }
}
void dog(group_node_t* temp,int cfd) //普通群员
{
     int simple=0;
    while(1)
    {

          pthread_mutex_lock(&mutex10);
         allcansee=-1;
         pthread_mutex_unlock(&mutex10);
        List_Free(glist,people_node_t);
        int time=0;
        struct work temp1={'v',0,0,"","",0};
        temp1.sid=temp->data.gid;
        send(cfd,&temp1,sizeof(struct work),0);
        while(1)
        {
            pthread_mutex_lock(&mutex10);
            if(allcansee==-1)
            {
                pthread_mutex_unlock(&mutex10);
                printf("等待服务器响应\n");
                 time++;
                if(time%5==0)
                {
                    send(cfd,&temp1,sizeof(struct work),0);
                }
                sleep(1);
              //  system("clear");
            }
            else{
                pthread_mutex_unlock(&mutex10);
                break;
            }
        }

       dog1:
        system("clear");
        char a;
          printf("============================ 群组管理 ============================\n");
        printf("欢迎你%-20s的群成员\n",temp->data.name);
        printf("                        输入'1'来查看群成员\n");
        printf("                        输入'2'来退出本群聊\n");
        printf("                        输入'3'来退出本界面\n");
        fflush(stdin);
        if (scanf("%c",&a)!=1)
        {
            printf("输入不合法,请重新输入\n");
            while(getchar()!='\n');
            goto dog1;
        }
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            getgroupmates(temp->data.gid,cfd);
            break;
            case '2':
            exitgroup(cfd,temp->data.gid);
            break;
            case '3':
            simple=1;
            break;
            default:
            printf("输入不合法,请重新输入\n");
            goto dog1;
            break;
        }
        if (simple==1)
        break;
    }
}
void grouphistory(int cfd)
{
   struct group_node *p;
    int id;
    grouph:
    system("clear");
    int i=0;
    printf("                        %-20s%-20s\n","群组id","群组名称");
    pthread_mutex_lock(&mutex4);
    List_ForEach(group1,p)
    {
        printf("                        %-20d%-20s\n",p->data.gid,p->data.name);
    }
    pthread_mutex_unlock(&mutex4);
    printf("请输入你要查看记录的群组id:\n");
    fflush(stdin);
    while(scanf("%d",&id)!=1)
    {
        printf("输入的不是有效的id!请重新输入\n");
        while(getchar()!='\n');
        goto grouph;
    }
    while(getchar()!='\n');
    List_ForEach(group1,p)
    {
       if (p->data.gid==id)
       {
           i=1;
           break;
       }
    }
    if (i==0)
    {
        printf("输入的不是有效的id!请输入回车后继续\n");
        while(getchar()!='\n');
        return;
    }
    fetchallgmes(cfd,id);
}
void transfile(int cfd)
{
    char choice;
    int simple=0;
    while(1)
    {
        system("clear");
        printf("============================ 传输文件 ============================\n");
        printf("                        输入'1'来查看待接收的文件\n");
        printf("                        输入'2'来发送一个文件\n");
        printf("                        输入'3'来退出出此界面\n");
        fflush(stdin);
        while(scanf("%c",&choice)!=1)
        {
            printf("输入不正确,请重新输入\n");
            while(getchar()!='\n');
        }
        while(getchar()!='\n');
        switch(choice)
        {
            case '1':
            rfile(cfd);
            break;
            case '2':
            sfile(cfd);
            break;
            case '3':
            simple=1;
            break;
            default:
             printf("输入不正确,请重新输入\n");
            break;
        }
        if (simple==1)
        break;
    }
}
void sfile(int cfd)
{
    int id;
    int fd;
    char filename[30];
    printf("输入你想传输的对象id号\n");
    if (scanf("%d",&id)!=1||!ismyfriend(id))
    {
        printf("无效的ID\n");
        while(getchar()!='\n');
        return;
    }getchar();
    
    printf("请输入正确的文件地址\n");
    scanf("%s",filename);getchar();
    struct work temp;
    temp.sid=myid;
    temp.rid=id;
    temp.tye='4';
    fd=open(filename,O_RDONLY,0664);
    if (fd==-1)
    {
        printf("open %s\n failed\n",filename);
        perror("open");
          printf("输入回车继续\n");
        while(getchar()!='\n');
        return;
    }
    struct stat stat_buf;
    fstat(fd,&stat_buf);
    temp.ret=stat_buf.st_size;
    strcpy(temp.name,find_file_name(filename));
    pthread_mutex_lock(&mutex10);
    allcansee=-1;
    pthread_mutex_unlock(&mutex10);
    send(cfd,&temp,sizeof(temp),0);
    sendfile(cfd,fd,NULL,stat_buf.st_size);
     while(1)
    {
        pthread_mutex_lock(&mutex10);
        if (allcansee==-1)
        {
            printf("等待服务器响应\n");
             pthread_mutex_unlock(&mutex10);
            sleep(1);
            system("clear");
        }
        else {pthread_mutex_unlock(&mutex10);
            printf("发送成功\n");
            printf("输入回车返回\n");
            while(getchar()!='\n');
            break;
        }
    }

}
void rfile(int cfd)
{   file asdsa;
    struct file_node *q;
    int simple=0;
    char a;
    while(1)
    {
        pthread_mutex_lock(&mutex10);
        allcansee=-1;
        pthread_mutex_unlock(&mutex10);
         List_Free(flist,file_node_t);
            struct work temp1={'5',0,0,"","",0};
            temp1.sid=myid;
            send(cfd,&temp1,sizeof(struct work),0);
            
            while(1)
            {
                pthread_mutex_lock(&mutex10);
                if (allcansee==-1)
                {
                      pthread_mutex_unlock(&mutex10);   
                    printf("等待客户端响应\n");
                    sleep(1);
                }
                else {
            pthread_mutex_unlock(&mutex10);
            break;
                }
            }

        system("clear");
    printf("============================ 传输文件 ============================\n");
    printf("                    %-20s%-20s%-20s%-20s%-20s\n","id","sid","文件名","大小","是否读取过");
    List_ForEach(flist,q)
    {
          printf("                    %-20d%-20d%-20s%-20d",q->data.id,q->data.sid,q->data.name,q->data.size);
          if (q->data.status)
          printf("%-20s\n","已下载");
          else printf("%-20s\n","未下载");
    }
    printf("                        输入'1'来选择一个文件下载\n");
    printf("                        输入'2'来在服务器上删除一个文件\n");
   // printf("                        输入'3'来刷新数据\n");
    printf("                        输入'3'来退出本界面\n");
     rfile1:
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            loadfile(cfd);
            break;
            case '2':
            delfile(cfd);
            break;
            case '3':
            simple=1;
            break;
            default:
            printf("不是一个合法选项,请重新输入\n");
            goto rfile1;
            break;
        }
        if (simple==1)
        {
            break;
        }
    }
    
}
void block()
{
    char a;int simple=0;
    while(1)
    {
        system("clear");
        black_node_t*p;
     printf("============================ 屏蔽好友 ============================\n");
    printf("                    %-20s%-20s\n","id","用户名");
    List_ForEach(blacklist,p)
    {
          printf("                    %-20d%-20s",p->data.id,p->data.name);
    }
     printf("                        输入'1'屏蔽一个好友\n");
    printf("                        输入'2'来取消屏蔽\n");
    printf("                        输入'3'来退出本界面\n");
     fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
           
            break;
            case '2':
            
            break;
            case '3':
            simple=1;
            break;
            default:
            printf("不是一个合法选项,请重新输入\n");
       //     goto rfile1;
            break;
        }
        if (simple==1)
        {
            break;
        }
    }
    
    
}
char *find_file_name(char *name)
{
	char *name_start = NULL;
	int sep = '/';
	if (NULL == name) {
			printf("the path name is NULL\n");
	    return NULL;
	}
	name_start = strrchr(name, sep);
 
	return (NULL == name_start)?name:(name_start + 1);
}
void delfile(int cfd)
{   struct file_node *q;
        int id;
        system("clear");
        struct work temp;
        temp.tye='7';
        List_ForEach(flist,q)
        {
            printf("%-20d%-20d%-20s%-20d",q->data.id,q->data.sid,q->data.name,q->data.size);
            if (q->data.status)
            printf("%-20s\n","已下载");
            else printf("%-20s\n","未下载");
        }
        printf("请选择想要删除的文件id:\n");
        if (scanf("%d",&id)!=1)
        printf("输入的不是一个id!\n");
        while(getchar()!='\n');
        List_ForEach(flist,q)
        {
            if (q->data.id==id)
                {
                    temp.sid=q->data.sid;
                    temp.rid=myid;
                    strcpy(temp.name,q->data.name);
                    temp.ret=q->data.size;
                    send(cfd,&temp,sizeof(temp),0);
                    break;
                }
                printf("输入了无效的id号\n");
        }printf("输入回车继续\n");
        
        while(getchar()!='\n');

}
void loadfile(int cfd)
{
    struct file_node *q;
        int id;
         pthread_mutex_lock(&mutex10);
        allcansee=-1;
        pthread_mutex_unlock(&mutex10);
        system("clear");
        struct work temp;
        temp.tye='6';
        List_ForEach(flist,q)
        {
            printf("%-20d%-20d%-20s%-20d",q->data.id,q->data.sid,q->data.name,q->data.size);
            if (q->data.status)
            printf("%-20s\n","已下载");
            else printf("%-20s\n","未下载");
        }
        printf("请选择想要下载文件id:\n");
        if (scanf("%d",&id)!=1)
        printf("输入的不是一个id!\n");
        while(getchar()!='\n');
        List_ForEach(flist,q)
        {
            if (q->data.id==id)
                {
                    temp.sid=q->data.sid;
                    temp.rid=myid;
                    strcpy(temp.name,q->data.name);
                    temp.ret=q->data.size;
                    send(cfd,&temp,sizeof(temp),0);
                      while(1)
                        {
                            pthread_mutex_lock(&mutex10);
                            if (allcansee==-1)
                            {
                                system("clear");
                                pthread_mutex_unlock(&mutex10);
                                printf("下载中.....\n");
                                sleep(1);
                            }
                            else {
                            pthread_mutex_unlock(&mutex10);
                            break;
                            }
                        }
                        printf("下载成功,输入回车继续\n");
                        while(getchar()!='\n');
                    return;
                }
               
        }
         printf("输入了无效的id号\n");
        printf("输入回车继续\n");
        
        while(getchar()!='\n');
}
void managefriend(int cfd)
{
    int simple=0;
    while(1)
    {
        pthread_mutex_lock(&mutex10);
        allcansee=-1;
         pthread_mutex_unlock(&mutex10);
          List_Free(list,people_node_t);
            struct work temp={'c',0,0,"","",0};
            temp.sid=myid;
            send(cfd,&temp,sizeof(struct work),0);
            while(1)
            {
                 pthread_mutex_lock(&mutex10);
                
                if (allcansee==-1)
                {
                    printf("等待服务器响应\n");
                     pthread_mutex_unlock(&mutex10);
                     sleep(1);
                }
                else {allcansee=-1;
                   pthread_mutex_unlock(&mutex10);
                    break;
                   }
            }
        system("clear");
          printf("============================ 好友管理 ============================\n");
        char a;
        printf("                        输入'1'来添加一个好友\n");
        printf("                        输入'2'来删除一个好友\n");
        printf("                        输入'3'来查看验证消息\n");
        printf("                        输入'4'来返回上层界面\n");
        fflush(stdin);
        scanf("%c",&a);
        while(getchar()!='\n');
        switch(a)
        {
            case '1':
            add_friend(cfd);
            break;
            case '2':
            delete_friend(cfd);
            break;
            case '3':
            getrequst(cfd);
            break;
            case '4':
            simple=1;
            break;
            default:
            printf("不是一个合法选项\n");
            break;
        }
         printf("按回车后继续\n");
         while(getchar()!='\n');
        if (simple==1)
            break;
    }
}

c.h

#ifndef _C_H
#define _C_H


#include "List.h"
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <termio.h>
#include<signal.h>
#include<sys/stat.h>
#include <stdio.h>       
#include <sys/sendfile.h>
#include<fcntl.h>                                                                                                           
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <strings.h>
#include <string.h>

typedef struct {
    int id;
    char name[30];
}black;
typedef struct black_node{
    black data;
    struct black_node*prev;
    struct black_node*next;
}black_node_t,*black_list_t;
typedef struct {
    int gid;
    char name[30];
    int power;
}group;
typedef struct {
    int id;
    int sid;
    char name[30];
    int size;
    int status;
}file;
typedef struct file_node{
    file data;
    struct file_node*prev;
    struct file_node*next;
}file_node_t,*file_list_t;
typedef struct group_node{
group data;
struct group_node*prev;
struct group_node*next;
}group_node_t,*group_list_t;
typedef struct {
    int xu;
    int sid;
    char name[20];
    int type;
}yan;
typedef struct {
int sid;
int rid;
char mes[1000];
}mes;
typedef struct mes_node{
    mes data;
    struct mes_node*prev;
    struct mes_node*next;
}mes_node_t,*mes_list_t;
typedef struct yan_node
{
    yan data;
    struct yan_node*prev;
    struct yan_node*next;
}yan_node_t, *yan_list_t;
typedef struct {
    int id;
    char name[20];
    int status;
}peple;
typedef struct people_node
{
    peple data;
    struct people_node*prev;
    struct people_node*next;
}people_node_t, *people_list_t;
struct work {
    char tye;
    int sid;
    int rid;
    char name[20];
    char password[20];
    int ret;
    char mes[1000];
};
int getch();
void *ralt(void* temp);
int ismyfriend(int id);
char *getgname(int id);
void yanzheng(int cfd);
void block();
void yanzhengg(int cfd,int gid);
void fetchallfriend(int cfd);
void fetchallmes(int cfd);
void fetchallgmes(int cfd,int gid);
void delete_friend(int cfd);
void getgroupmates(int gid,int cfd);
void add_friend(int cfd);
void chatwithf(int cfd);
void chatwithg(int cfd);
void getrequst(int cfd);
void grouphistory(int cfd);
char *find_file_name(char *name);
int isonline(int fd);
int logon(struct work temp,int cfd);
int login(struct work temp,int cfd);
int SysLogin(int efd);  // SL界面
int SysLogon(int efd);
void managefriend(int cfd);
void creategroup(int cfd);
void joingroup(int cfd);
void getgroup(int cfd);
void managegroup(int cfd);
void owner(group_node_t* temp,int cfd);
void delfile(int cfd);
void loadfile(int cfd);
void admin(group_node_t* temp,int cfd);
void dog(group_node_t* temp,int cfd);
void setadmin(int gid,int cfd);
void exitgroup(int cfd,int gid);
void deletemate(int gid,int cfd);
void getgrequst(group_node_t* temp,int cfd);
void sfile(int cfd);
void rfile(int cfd);
void transfile(int cfd);
#endif

mysqlc.h

#ifndef MYSQLC_H_
#define MYSQLC_H_

#include <netinet/in.h>   
#include <arpa/inet.h>
#include <string.h>  
#include <stdio.h>
#include <stdlib.h>
#include"List.h"
#include<sys/sendfile.h>
#include<sys/stat.h>
#include <sys/sendfile.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <pthread.h>

#include <mysql/mysql.h>
struct s1 {
    int epfd,conn_fd;
};
struct work {
    char tye;
    int sid;
    int rid;
    char name[20];
    char password[20];
    int ret;
    char mes[1000];
};
typedef struct {
    int id;
    char name[20];
    int fd;
}peple;
typedef struct people_node
{
    peple data;
    struct people_node*prev;
    struct people_node*next;
}people_node_t, *people_list_t;
void my_err(const char *error_string, int line);
MYSQL accept_mysql(void);
int close_mysql(MYSQL mysql);
int use_mysql(const char *name,const char *password,MYSQL mysql1);
int use_mysql_2(const char *name,MYSQL mysql1);
int use_mysql_3(int id,MYSQL mysql1);
int use_mysql_6(int id,MYSQL mysql1);
int use_mysql_10(struct work temp,MYSQL mysql1);
char* use_mysql_7(int id,MYSQL mysql1);
int use_mysql_18(int gid,int sid,MYSQL mysql1);
int use_mysql_4(int id,MYSQL mysql1);
int use_mysql_21(int gid,int cfd,MYSQL mysql1);
int use_mysql_1(const char *name,const char *password,MYSQL mysql1);
int judege(const char *name,const char *password);
int judegeon(const char *name,const char *password);
void getmyrequst(int id);
void getmyfriend(int id);
char *yourname(int id);
int ishe(int id,struct s1 *s);
void getallngmes(int gid,int sid,int cfd);
int getstatus(int id);
int getcfd(int id);
int find_byname(const char*name);
void add_friends(struct work temp);
void disagree(struct work temp);
void agree(struct work temp);
void agreeg(struct work temp);
void disagreeg(struct work temp);
void delete_friend(struct work temp);
void ssend_mes(struct work temp);
void read_mes(struct work temp);
void read_gmes(struct work s1);
void getallnmes(int id);
void getallgmes(int gid,int sid,int cfd);
void getmates(int gid,int cfd);
void createg(struct work temp);
void sendallmes(int id);
void delmate(struct work s1,int cfd);
void setadmin(struct work s1,int cfd);
void joingroups(struct work temp);
void getmygroup(int id);
char* genRandomString(int length);
void savefile(struct work s1,char *filename);
int use_mysql_23(struct work s1,MYSQL mysql1);
void killgroup(int gid);
void delete_file(struct work s1);
void send_file(struct work s1);
void sendfilelist(struct work s1);
int use_mysql_24(int gid,MYSQL mysql1);
void getmygrequst(int gid,int sid);
void gsend_mes(struct work s1);
ssize_t						/* Read "n" bytes from a descriptor. */
readn(int fd, void *vptr, size_t n);
#endif

List,h

/*
 * Copyright(C), 2007-2008, XUPT Univ.
 * File name: list.h
 * Description : 链表操作宏定义、分页操作
 * Author:   XUPT
 * Version:  v.1
 * Date: 	2015年4月22日
 */

#ifndef LIST_H_
#define LIST_H_

#include <assert.h>
#include <stdlib.h>

/*初始化链表list。链表为带头结点的双向循环链表*/
#define List_Init(list, list_node_t)                               \
    {                                                              \
        list         = (list_node_t *)malloc(sizeof(list_node_t)); \
        (list)->next = (list)->prev = list;                        \
    }

//释放链表list中所有数据结点。list 为链表头指针,list_node_t为链表结点类型
#define List_Free(list, list_node_t)            \
    {                                           \
        assert(NULL != list);                   \
        list_node_t *tmpPtr;                    \
        (list)->prev->next = NULL;              \
        while (NULL != (tmpPtr = (list)->next)) \
        {                                       \
            (list)->next = tmpPtr->next;        \
            free(tmpPtr);                       \
        }                                       \
        (list)->next = (list)->prev = list;     \
    }

//销毁链表list,释放所有数据结点及头结点。
// list为链表头指针,tmpPtr为链表结点临时指针变量
#define List_Destroy(list, list_node_t)          \
    {                                            \
        assert(NULL != list);                    \
        List_Free(list, list_node_t) free(list); \
        (list) = NULL;                           \
    }

//链表头插法,list为头指针,new为新节点
#define List_AddHead(list, newNode)        \
    {                                      \
        (newNode)->next    = (list)->next; \
        (list)->next->prev = newNode;      \
        (newNode)->prev    = (list);       \
        (list)->next       = newNode;      \
    }

//链表尾插法,list为头指针,new为新节点
#define List_AddTail(list, newNode)        \
    {                                      \
        (newNode)->prev    = (list)->prev; \
        (list)->prev->next = newNode;      \
        (newNode)->next    = list;         \
        (list)->prev       = newNode;      \
    }

//将新节点newNode加入到node之前
#define List_InsertBefore(node, newNode)      \
    {                                         \
        (newNode)->prev       = (node)->prev; \
        (newNode)->next       = node;         \
        (newNode)->prev->next = newNode;      \
        (newNode)->next->prev = newNode;      \
    }

//将新节点newNode加入到node之后
#define List_InsertAfter(node, newNode)     \
    {                                       \
        (newNode)->next       = node->next; \
        (newNode)->prev       = node;       \
        (newNode)->next->prev = newNode;    \
        (newNode)->prev->next = newNode;    \
    }

//判断链表是否为空,list为头指针
#define List_IsEmpty(list) \
    ((list != NULL) && ((list)->next == list) && (list == (list)->prev))

//从删除链表结点node,
#define List_DelNode(node)                                                    \
    {                                                                         \
        assert(NULL != node && node != (node)->next && node != (node)->prev); \
        (node)->prev->next = (node)->next;                                    \
        (node)->next->prev = (node)->prev;                                    \
    }

//从链表中删除并释放结点node
#define List_FreeNode(node) \
    {                       \
        List_DelNode(node); \
        free(node);         \
    }

//使用指针curPos依次遍历链表list
#define List_ForEach(list, curPos) \
    for (curPos = (list)->next; curPos != list; curPos = curPos->next)

//分页数据结构体,简称分页器类型
typedef struct
{
    int totalRecords;  //总记录数
    int offset;  //当前页起始记录相对于第一条记录的偏移记录数
    int pageSize;  //页面大小
    void *curPos;  //当前页起始记录在链表中的结点地址
} Pagination_t;

//根据分页器paging的偏移量offset将分页器定位到链表list的对应位置
#define List_Paging(list, paging, list_node_t)                      \
    {                                                               \
        if (paging.offset + paging.pageSize >= paging.totalRecords) \
        {                                                           \
            Paging_Locate_LastPage(list, paging, list_node_t);      \
        }                                                           \
        else                                                        \
        {                                                           \
            int i;                                                  \
            list_node_t *pos = (list)->next;                        \
            for (i = 0; i < paging.offset && pos != list; i++)      \
                pos = pos->next;                                    \
            paging.curPos = (void *)pos;                            \
        }                                                           \
    }

//将分页器paging定位到链表list的第一页
#define Paging_Locate_FirstPage(list, paging)   \
    {                                           \
        paging.offset = 0;                      \
        paging.curPos = (void *)((list)->next); \
    }

//将分页器paging定位到链表list的最后一页
#define Paging_Locate_LastPage(list, paging, list_node_t)           \
    {                                                               \
        int i = paging.totalRecords % paging.pageSize;              \
        if (0 == i && paging.totalRecords > 0) i = paging.pageSize; \
        paging.offset    = paging.totalRecords - i;                 \
        list_node_t *pos = (list)->prev;                            \
        for (; i > 1; i--) pos = pos->prev;                         \
        paging.curPos = (void *)pos;                                \
    }

//对于链表list及分页器paging,使用指针curPos依次遍历paging指向页面中每个结点
//这里i为整型计数器变量
#define Paging_ViewPage_ForEach(list, paging, list_node_t, pos, i) \
    for (i = 0, pos = (list_node_t *)(paging.curPos);              \
         pos != list && i < paging.pageSize; i++, pos = pos->next)

//对于链表list,将分页器paging向前(后)移动offsetPage个页面.
//当offsetPage<0时,向前(链表头方向)移动|offsetPage|个页面
//当offsetPage>0时,向后(链末尾方向)移动offsetPage个页面
#define Paging_Locate_OffsetPage(list, paging, offsetPage, list_node_t) \
    {                                                                   \
        int offset       = offsetPage * paging.pageSize;                \
        list_node_t *pos = (list_node_t *)paging.curPos;                \
        int i;                                                          \
        if (offset > 0)                                                 \
        {                                                               \
            if (paging.offset + offset >= paging.totalRecords)          \
            {                                                           \
                Paging_Locate_LastPage(list, paging, list_node_t);      \
            }                                                           \
            else                                                        \
            {                                                           \
                for (i = 0; i < offset; i++) pos = pos->next;           \
                paging.offset += offset;                                \
                paging.curPos = (void *)pos;                            \
            }                                                           \
        }                                                               \
        else                                                            \
        {                                                               \
            if (paging.offset + offset <= 0)                            \
            {                                                           \
                Paging_Locate_FirstPage(list, paging);                  \
            }                                                           \
            else                                                        \
            {                                                           \
                for (i = offset; i < 0; i++) pos = pos->prev;           \
                paging.offset += offset;                                \
                paging.curPos = pos;                                    \
            }                                                           \
        }                                                               \
    }

//根据分页器paging计算当前的页号
#define Pageing_CurPage(paging) \
    (0 == (paging).totalRecords ? 0 : 1 + (paging).offset / (paging).pageSize)

//根据分页器paging计算的总的页数
#define Pageing_TotalPages(paging)                    \
    (((paging).totalRecords % (paging).pageSize == 0) \
         ? (paging).totalRecords / (paging).pageSize  \
         : (paging).totalRecords / (paging).pageSize + 1)

//根据paging判断当前页面是否为第一页。结果为true表示是,否则false
#define Pageing_IsFirstPage(paging) (Pageing_CurPage(paging) <= 1)

//根据paging判断当前页面是否为最后一页。结果为true表示是,否则false
#define Pageing_IsLastPage(paging) \
    (Pageing_CurPage(paging) >= Pageing_TotalPages(paging))

#endif /* LIST_H_ */

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值