学习Linux网络编程实现小项目-聊天室(0)--源码以及项目部署遇到的问题以及解决

明明聊天室是要在暑假两个星期内写完的,由于疫情没有回校学习,在家也是写一点放松一点,并且第一次写一个比较大的项目有点力不从心,总之有遗憾吧,在网络编程这块学习也是浅上折纸,在想整体架构上有明显不足,所以导致了第一版问题比较多,在垂头丧气了几天感觉自己目前能力解决不了的情况下选择了重写,过程比较痛苦,也焦虑了几夜,躺着也难受想放弃,不知道选这个有没有错,还是说自学并没有什么作用,菜是菜了点,好歹挺过来了。。。然后又是测试,学长帮我测了四次来慢慢解决一些逻辑漏洞,逐渐也熟悉了这部分的要求,再看看别人的实现和对网络编程的理解,有羡慕,也有难过,逃避宣泄着情绪,小城无路可逃。我先看到了这里,然后感受非常复杂。

该程序仅在本机上测试通过,部署到公网上时出现的getch()回显问题以及登录不上一些问题(这个可以重启client端完成登录),应该是加锁和数据阻塞的原因,由于不想改了如果有大佬看到这篇博客希望能给一些建议和帮助

我的ubuntu的版本

Linux version 5.4.0-42-generic (buildd@lgw01-amd64-038) linux内核版本号
gcc version 9.3.0 gcc编译器版本号
Ubuntu 9.3.0-10ubuntu2 Ubuntu版本号
  1. 加好友和加群
    一般客户端发送一个请求消息给服务器后,服务器再发给客户端一个添加消息,客户端用盒子链表来存,再输入同意与否,处理一条删除一条,最后发送回执给服务器,服务器判断是否同意再发回客户端显示消息
  2. 离线私聊和群聊
    私聊要判断有没有屏蔽,是否是好友,在不在线,不在线采用离线status位存发送与否先存mysql库里面,等对面上线了由服务器发送消息,群聊多加了是否是存在群和是否是群成员判断,以及查找发送给其他群成员的mysql查找
  3. 文件传输
    由于实现的框架局限,这部分之前版本有些内存泄漏和栈溢出的问题,之后查到了sendfile和splice的Linux零拷贝方法,但是在参考后还是选择了上传服务器和客户端再下载的实现,注意传输的数据要完全最后要加一个消息通知服务器传输完成
  4. 如果不太明白一些具体逻辑的实现可以私聊我,后面看时间会不会写一个解释博客,估计是不会了

以下是代码实现

server.c
#include "chat.h"
#define EPOLLEVENT 1024
#define BUFMAX 1024
#define BUF 2048


char *Server_time();
int	Set_no_block(int sfd);

int sys_log;
MYSQL mysql;

/*
void Add_node(int fd,int id,char* name);
void Send_register_pack(int fd,int flag,char* buf,int id);
int Get_status(int id);
char* Get_name(int id);*/
int main()
{
   

   


    /*if((sys_log=open("sys_log",O_WRONLY | O_CREAT | O_APPEND,S_IRUSR|S_IWUSR))<0)
    {
        sys_err("open error",__LINE__);
        return 0;
    }
    dup2(sys_log,1);*/

    
    signal(SIGINT,Signal_close);

    //pthread_mutex_init(&mutex,NULL);
    //pthread_cond_init(&cond,NULL);

    Connect_mysql();
    /*printf("线程池启动\n");
    pool_init(MAX_THREAD_NUM);
    printf("线程池启动成功!\n");
    sleep(2);*/
    pool_init(50);
    //sleep(2);
    //Read_from_mysql();
    Init_socket();


    //threadpool_destroy();

}
void Signal_close(int i)
{
   
    close(sys_log);
    Close_mysql(mysql);
    printf("服务器关闭\n");
    exit(1);
}


char *Server_time()
{
   
	time_t ctime;//服务器时间
	struct tm *server_time;
	time(&ctime);
	server_time=localtime(&ctime);
	return asctime(server_time);
}

int	Set_no_block(int sfd)
{
   
	/* 内层调用fcntl()的F_GETFL获取flag,
	 * 外层fcntl()将获取到的flag设置为O_NONBLOCK非阻塞*/
	if( fcntl(sfd, F_SETFL, fcntl(sfd, F_GETFL, 0) ) == -1)
	{
   	
        return -1;
    }
	return 0;
}

void Init_socket(int argc,char *argv[])
{
   
    struct stat stat_buf;
	const char* file_name=argv[1];   
    int file_fd=open(file_name,O_RDONLY);
	fstat(file_fd,&stat_buf);
	close(file_fd); 

    List_Init(list_ser,server_user_node_t);
    printf("服务端启动\n");
    struct sockaddr_in serv_addr;
    struct sockaddr_in cli_addr;

    socklen_t cli_addr_len;

    lfd=Socket(AF_INET,SOCK_STREAM,0);


    Set_no_block(lfd);
    //端口复用
    int opt=1;
    setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt));

    bzero(&serv_addr,sizeof(serv_addr));

    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(SERV_PORT);
    serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);

    Bind(lfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
    Listen(lfd,128);

    printf("服务器启动成功!\n");

    epfd=epoll_create(EPOLLEVENT);
    struct epoll_event tep,ep[EPOLLEVENT];
    tep.events=EPOLLIN;
    tep.data.fd=lfd;
    epoll_ctl(epfd,EPOLL_CTL_ADD,lfd,&tep);

    int i;
    int ret;
    pthread_t pid;
    char buf[BUFMAX];
    //memset(buf,0,sizeof(buf));
    while(1)
    {
   
        ret=epoll_wait(epfd,ep,EPOLLEVENT,-1);
        for(i=0;i<ret;i++)
        {
   

            //printf("the event is %x\n",ep[i].events);
            int fd=ep[i].data.fd;

            if (!(ep[i].events & EPOLLIN))      //如果不是"读"事件, 继续循环
                continue;

            if(ep[i].data.fd==lfd)
            {
   
                cli_addr_len=sizeof(cli_addr);
                cfd=Accept(lfd,(struct sockaddr*)&cli_addr,&cli_addr_len);
                printf("连接到新的客户端ip:%s\n端口号:%d\n",inet_ntoa(cli_addr.sin_addr),cli_addr.sin_port);
                
                /*设置非阻塞io*/
				if(Set_no_block(cfd) != 0 )
				{
   
					printf("SET_no_black\n");
					printf("%s",Server_time());
					close(cfd);
					continue;
				}
                
                tep.events=EPOLLIN;
                tep.data.fd=cfd;
                if(epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&tep)<0)
                {
   
                    printf("EPOLL_CTL add client error\n");
                    printf("%s",Server_time());
					
                    close(cfd);
					continue;
                }

            }
            /*else if(ep[i].events & EPOLLOUT) 
            {
                printf("start to sendfile !\n");
                printf("处理写事件\n");
                int write;
                write=send(fd,buf,strlen(buf),0);
                if(write == -1)
                {
                    my_err("write event error",__LINE__);
                    close(fd);
                }
                else
                {
                    printf("发送消息成功\n");
                }
                memset(buf,0,BUFMAX);
            }*/
            /*else if(ep[i].events & EPOLLOUT)
            {

				printf("start to sendfile !\n");
				int send_ret=0;
                int left=stat_buf.st_size;
				file_fd=open(file_name,O_RDONLY);

				while(left>0)
                {
					send_ret=sendfile(cfd,file_fd,NULL,BUF);
					if(send_ret<0 && errno==EAGAIN)
                    {
						continue;
					}
                    else if(send_ret==0)
                    {
						break;
					}
                    else
                    {
						left-=send_ret;
					}
				}

				printf("sendfile over !\n");
				close(file_fd);

				tep.data.fd=cfd;
				epoll_ctl(epfd,EPOLL_CTL_DEL,cfd,&tep);

				close(cfd);
            }*/
            else if(ep[i].events & EPOLLIN)
            {
   
                memset(buf,0,sizeof(buf));
                int n=recv(ep[i].data.fd,buf,sizeof(buf),MSG_WAITALL);
                int fd=ep[i].data.fd;
                printf("\n");
                /*printf("%d\n",recv_t.data.send_fd);
                printf("%d\n",recv_t.data.recv_fd);
                printf("server message%s\n",recv_t.data.message);
                printf("server recv:%s\n",recv_t.data.send_name);*/


                if(n<0)
                {
   
                    close(ep[i].data.fd);
                    sys_err("recv error!",__LINE__);
                    continue;
                }
                else if(n==0)
                {
   
                    printf("??????\n");
                    server_list_t pos;
                    List_ForEach(list_ser,pos)
                    {
   
                        if(pos->data.connfd==ep[i].data.fd)
                        {
       
                            printf("sssssssssssss\n");
                           
                            char buf_t[BUFSIZ];
                            sprintf(buf_t,"update account set status=0 where id=%d",pos->data.id);
                            printf("buf_t:%s\n",buf_t);
                            int ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
                            if(ret)
                            {
   
                                Mysql_with_error(&mysql);
                            }
                            //printf("用户[%d]已经下线\n",pos->data.id);
                            printf("账号[%d]下线了:%d\n",pos->data.id,pos->data.connfd);

                            List_FreeNode(pos);  
                            break;
                        }
                    }
                    tep.data.fd=ep[i].data.fd;
                    printf("客户端:%d连接断开\n",tep.data.fd);
                   
                    epoll_ctl(epfd,EPOLL_CTL_DEL,ep[i].data.fd,&tep);
                    close(ep[i].data.fd);
                    continue;
                }

                int flag;
                memcpy(&flag,buf,sizeof(int));
                printf("flag:%d\n",flag);
                
                switch(flag)
                {
   
                    case LOGIN:
                        Login(fd,buf);
                        break;
                    case REGISTER:
                        Register(fd,buf);
                        break;
                    case EXIT:
                        Exit(fd,buf);
                        break;
                    case ADD_FRIEND:
                        Add_friend(fd,buf);
                        break;
                    case ADD_FRIEND_ACCEPT:
                        Add_friend_accept(fd,buf);
                        break;
                    case DEL_FRIEND:
                        Del_friend(fd,buf);
                        break;
                    case PRIVATE_CHAT:
                        Private_chat(fd,buf);
                        break;
                    //写在一起比较好
                    //case SHOW_FRIEND_STATUS:
                    case VIEW_FRIEND_LIST:
                        View_friend_list(fd,buf);
                        break;
                    case SHIELD:
                        Shield_friend(fd,buf);
                        break;
                    case UNSHIELD:
                        Unshield_friend(fd,buf);
                        break;
                    case VIEW_CHAT_HISTORY:
                        View_chat_history(fd,buf);
                        break;
                    case CREAT_GROUP:
                        Create_group(fd,buf);
                        break;
                    case ADD_GROUP:
                        Add_group(fd,buf);
                        break;
                    case ADD_GROUP_ACCEPT:
                        Add_group_accept(fd,buf);
                        break;
                    case WITHDRAW_GROUP:
                        Withdraw_group(fd,buf);
                        break;
                    //一起实现
                    case VIEW_GROUP_MEMBER:
                        View_group_member(fd,buf);
                        break;
                    case VIEW_ADD_GROUP:
                        View_add_group(fd,buf);
                        break;
                    case SET_GROUP_ADMIN:
                        Set_group_admin(fd,buf);
                        break;
                    case KICK:
                        Kick(fd,buf);
                        break;
                    case GROUP_CHAT:
                        Group_chat(fd,buf);
                        break;
                    case VIEW_GROUP_RECORD:
                        View_group_record(fd,buf);
                        break;
                    /*case SEND_FILE:
                        printf("here\n");
                        {
                            printf("111111111111111\n");
                            char *buf1=(char*)malloc(sizeof(1024));
                            printf("22222222222222222\n");
                            memcpy(buf1,buf,sizeof(file_t));
                            printf("333333333333333333\n");
                            threadpool_add(Send_file,(void*)buf1);*/
                            /*printf("....\n");
                            file_t file;
                            char *str=(char*)malloc(sizeof(file));
                            memcpy(str,buf,sizeof(file));
                            pthread_t recv_file_id;
                            pthread_create(&recv_file_id,NULL,Send_file,(void*)str);
                            printf(">>>>\n");*/
                            
                            //Send_file(fd,buf);
                            //break;
                        //}
                    case SEND_FILE:
                        break;
                    case UPLOAD:
                        Upload(fd,buf);
                        break;;
                    /*case RECV_FILE:
                        //Recv_file(fd,buf);
                        break;*/
                    case DOWNLOAD:
                        Download(fd,buf);
                        break;
                    case 0:
                        break;
                }
            }
        }
    }
    close(epfd);
    close(lfd);
}

void Register(int fd,char* buf)
{
   
    Account_t account;
    memcpy(&account,buf,sizeof(account));
    printf("server name:%s\n",account.name);
    printf("server password:%s\n",account.password);
    server_user_t user;
    strcpy(user.name,account.name);
    strcpy(user.password,account.password);
    printf("server username:%s\n",user.name);
    printf("server password:%s\n",user.password);

    account.online=DOWNLINE;

   
    
    char buf_t[BUFSIZ];
    sprintf(buf_t,"insert into account values(NULL,'%s','%s','%d')",account.name,account.password,account.online);
    printf("buf_t:%s\n",buf_t);
    int ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
        printf("注册失败\n");
        /*char mes[256];
        sprintf(mes,"你输入的名称[%s]有误,请重新输入",account.name);
        Send_pack(fd,REGISTER_ERROR_APPLY,mes);*/
    }
    else 
        printf("注册成功\n");

    memset(buf_t,0,sizeof(buf_t));
    sprintf(buf_t,"select LAST_INSERT_ID()");
    printf("buf_t:%s\n",buf_t);
    ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
    }
    MYSQL_RES *result;  
    MYSQL_ROW  row;
    result=mysql_store_result(&mysql);
    row=mysql_fetch_row(result);
    int id=atoi(row[0]);
    printf("server username:%d",id);
    char str[256];
    //strcpy(str,account.username);
    sprintf(str,"账号[%d]注册成功",id);
    Send_register_pack(fd,REGISTER_APPLY,str,id);
    printf("666666666\n");   
}               


void Send_register_pack(int fd,int flag,char* buf,int id)
{
   
    char str[BUFSIZ];
    message mes;

    mes.flag=flag;
    mes.id=id;
    strcpy(mes.message,buf);
    printf("server send message:%s\n",mes.message);
    memcpy(str,&mes,sizeof(mes));
    
    printf("server send id:%d\n",mes.id);
    printf("server send flag:%d\n",mes.flag);
    if(send(fd,str,sizeof(str),0)<0)
    {
   
        my_err("send error!",__LINE__);
        close(fd);
    }
}


void Login(int fd,char* buf)
{
   
    Account_t account;
    memcpy(&account,buf,sizeof(account));
    printf("server id:%d\n",account.id);
    printf("server password:%s\n",account.password);
    char name[MAX];
    
    
    int send_fd=Get_connfd(account.id);
    /*server_list_t pos;
    List_ForEach(list_ser,pos)
    {
        if(pos->data.id==account.id)
        {
            send_fd=pos->data.connfd;
        }
    }*/
    if(send_fd>0)
    {
   
        printf("账号已登录\n");
        Send_pack(fd,LOGIN_APPLY,"a");
        return ;
    }


    char buf_t[BUFSIZ];
    sprintf(buf_t,"select *from account where id=%d",account.id);
    printf("buf_t:%s\n",buf_t);
    int ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
    }
    MYSQL_RES *result;  
    MYSQL_ROW  row;
    result=mysql_store_result(&mysql);
    row=mysql_fetch_row(result);
        //printf("row[0]:%s\n",row[0]);
    if(row==NULL)
    {
   
        printf("/\n");
        /*char mes[256];
        sprintf(mes,"密码错误或者账号不存在!\n");
        Send_pack(fd,LOGIN_APPLY,mes);*/
        Send_pack(fd,LOGIN_APPLY,"n");
        return ;
    }
    
    else
    {
   
        printf("row[0]:%s\n",row[0]);
        //if(strcmp(row[0],user.username)==0)
        //{
   
          //  memset(buf_t,0,sizeof(buf_t));
            //sprintf(buf_t,"select username from account");
            //printf("buf_t:%s\n",buf_t);
            strcpy(name,row[1]);
            printf("name:%s\n",row[1]);
            if(strcmp(row[2],account.password)==0)
            {
   
                Add_node(fd,account.id,name);
                server_list_t p;
                List_ForEach(list_ser,p)
                {
   
                    printf("username:%d\n",p->data.id);
                    printf("connfd:%d\n",p->data.connfd);
                    printf("name:%s\n",p->data.name);
                }
                Send_pack(fd,LOGIN_APPLY,"y");
                memset(buf_t,0,sizeof(buf_t));
                sprintf(buf_t,"update account set status=1 where id=%d",account.id);
                printf("buf_t:%s\n",buf_t);
                int ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
                if(ret)
                {
   
                    Mysql_with_error(&mysql);
                }
                printf("[%d]登录成功\n",account.id);
                Send_offline_apply(fd,account.id);
                Send_offline_messgae(fd,account.id);

            }
            else
                Send_pack(fd,LOGIN_APPLY,"n");
        //}
    }
}
void Send_offline_apply(int fd,int recver)
{
   
    char buf[BUFSIZ];
    sprintf(buf,"select *from friend where (fid=%d and  request=%d)",recver,0);
    printf("buf=%s\n",buf);
    int ret=mysql_real_query(&mysql,buf,strlen(buf));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
        printf("您暂无离线好友申请消息\n");
    }
    MYSQL_RES *result;
    MYSQL_ROW  row;
    result=mysql_store_result(&mysql);
    
    while((row=mysql_fetch_row(result)))
    {
   
        char buf[BUFSIZ];
        sprintf(buf,"update friend set request=2 where fid=%d",atoi(row[1]));
        printf("buf=%s\n",buf);
        int ret=mysql_real_query(&mysql,buf,strlen(buf));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
        char mes[256];
        int requester=atoi(row[0]);
        sprintf(mes,"用户[%d]请求加你为好友",requester);
        Send_connfd_pack(ADD_FRIEND_APPLY,requester,recver,mes);
        printf("[%d]对好友[%d]好友申请发送成功\n",requester,recver);
    }


    memset(buf,0,sizeof(buf));
    sprintf(buf,"select sid from group_request where (mid=%d and request=2)",recver);
    printf("buf=%s\n",buf);
    ret=mysql_real_query(&mysql,buf,strlen(buf));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
    }
    MYSQL_RES *result2;
    MYSQL_ROW  row2;
    result2=mysql_store_result(&mysql);
    //row2=mysql_fetch_row(result2);

   
    while((row2=mysql_fetch_row(result2)))
    {
      
         printf("row2[0]:%d\n",atoi(row2[0]));
       
            char buf[BUFSIZ];

            char mes[256];
            int requester=atoi(row2[0]);
            sprintf(mes,"用户[%d]请求加入群聊",atoi(row2[0]));
            Send_connfd_pack(ADD_GROUP_APPLY,requester,recver,mes);
            printf("[%d]对群管理[%d]的群申请发送成功\n",requester,recver);


            sprintf(buf,"update group_member set request=1 where mid=%d",atoi(row2[0]));
            printf("buf:%s\n",buf);
            ret=mysql_real_query(&mysql,buf,strlen(buf));
            if(ret)
            {
   
                Mysql_with_error(&mysql);
            }


             memset(buf,0,sizeof(buf));
            sprintf(buf,"update group_request set request=1 where mid=%d",recver);
            printf("buf:%s\n",buf);
            ret=mysql_real_query(&mysql,buf,strlen(buf));
            if(ret)
            {
   
                Mysql_with_error(&mysql);
            }
    }

}
void Send_offline_messgae(int fd,int recver)
{
   
    char buf[BUFSIZ];
    memset(buf,0,sizeof(buf));
    sprintf(buf,"select *from chat_message where (fid=%d and status=%d)",recver,0);
    printf("buf=%s\n",buf);
    int ret=mysql_real_query(&mysql,buf,strlen(buf));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
    }
    MYSQL_RES *result;
    MYSQL_ROW  row;
    result=mysql_store_result(&mysql);

    while((row=mysql_fetch_row(result)))
    {
   

        char str[BUFSIZ];
        sprintf(str,"select *from account where id=%d",atoi(row[0]));
        printf("str:%s\n",str);
        int ret=mysql_real_query(&mysql,str,strlen(str));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
        MYSQL_RES *result1;
        MYSQL_ROW row1;
        result1=mysql_store_result(&mysql);
        row1=mysql_fetch_row(result1);

        char name[MAX];
        strcpy(name,row1[1]);


        char buf[BUFSIZ];
        sprintf(buf,"update chat_message set status=2 where fid=%d",recver);
        printf("buf=%s\n",buf);
        ret=mysql_real_query(&mysql,buf,strlen(buf));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
        Chat_message mes_t;
        mes_t.flag=PRIVATE_CHAT_APPLY;
        mes_t.sender=atoi(row[0]);
        mes_t.recver=atoi(row[1]);
        strcpy(mes_t.message,row[2]);
        /*char str[BUFSIZ];
        memcpy(str,&mes_t,sizeof(mes_t));
        if(send(fd,buf,sizeof(buf),0)<0)
        {
            my_err("send error!",__LINE__);
        }*/
        char mes[256];
        sprintf(mes,"\033[;33m\33[1m%d\t\033[;32m\33[1m%s\t\033[;31m\33[1m%s\033[0m",mes_t.sender,name,mes_t.message);
        Send_pack(fd,PRIVATE_CHAT_APPLY,mes);
        printf("[%d]有对[%d]的离线聊天\n",mes_t.sender,mes_t.recver);
    }


    memset(buf,0,sizeof(buf));
    sprintf(buf,"select *from group_message where (recv_name=%d and status=0)",recver);
    printf("buf=%s\n",buf);
    ret=mysql_real_query(&mysql,buf,strlen(buf));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
    }
    MYSQL_RES *result1;
    MYSQL_ROW  row1;
    result1=mysql_store_result(&mysql);
    while((row1=mysql_fetch_row(result1)))
    {
   

        char str[BUFSIZ];
        sprintf(str,"select *from account where id=%d",atoi(row1[0]));
        printf("str:%s\n",str);
        int ret=mysql_real_query(&mysql,str,strlen(str));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
        MYSQL_RES *result2;
        MYSQL_ROW row2;
        result2=mysql_store_result(&mysql);
        row2=mysql_fetch_row(result2);

        char name[MAX];
        strcpy(name,row2[1]);




        Chat_message mes_t;
        mes_t.flag=GROUP_CHAT_APPLY;
        mes_t.sender=atoi(row1[0]);
        mes_t.recver=atoi(row1[1]);
        strcpy(mes_t.message,row1[2]);
        /*char str[BUFSIZ];
        memcpy(str,&mes_t,sizeof(mes_t));
        if(send(fd,buf,sizeof(buf),0)<0)
        {
            my_err("send error!",__LINE__);
        }*/
         char mes[256];
         sprintf(mes,"[%d]\t%s\t%s",mes_t.sender,name,mes_t.message);

         Send_pack(fd,GROUP_CHAT_APPLY,mes);
        printf("[%d]有对群的离线聊天\n",mes_t.sender);


        char buf[BUFSIZ];
        sprintf(buf,"update group_message set status=1 where recv_name=%d",recver);
        printf("buf=%s\n",buf);
        ret=mysql_real_query(&mysql,buf,strlen(buf));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
    }


}
void Exit(int fd,char* buf)
{
   
    message mes;
    memcpy(&mes,buf,sizeof(mes));
    printf("server recv message:%s\n",mes.message);

    char buf_t[BUFSIZ];
    sprintf(buf_t,"update account set status=0 where id=%d",mes.id);
    printf("buf_t:%s\n",buf_t);
    int ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
    }
    printf("用户[%d]已经下线\n",mes.id);
    
    //char mes1[256];
    //sprintf(mes1,"您[%d]已退出",mes.id);
    //Send_pack(fd,EXIT_APPLY,mes1);

}

void Add_node(int fd,int id,char* name)
{
   
    server_list_t pos=(server_list_t)malloc(sizeof(server_user_node_t));
    pos->data.connfd=fd;
    pos->data.id=id;
    strcpy(pos->data.name,name);
    printf("pos->data.connfd:%d\n",pos->data.connfd);
    printf("pos->data.id=%d\n",pos->data.id);
    printf("pos->data.name=%s\n",pos->data.name);
    List_AddTail(list_ser,pos);
}
void Add_friend(int fd,char* buf)
{
   

    Relation_t relation;
    memcpy(&relation,buf,sizeof(relation));
    printf("server/ friend send:%d\n",relation.send);
    printf("server/ friend recv:%d\n",relation.recv);
    printf("server/ friend message:%s\n",relation.message);

    char buf_t[BUFSIZ];
    //查询有没有这两个人的账号
    sprintf(buf_t,"select request from friend where (uid=%d and fid=%d) or (uid=%d and fid=%d)",relation.send,relation.recv,relation.recv,relation.send);
    printf("buf_t:%s\n",buf_t);
    int ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
    if(ret)
    {
   
        Mysql_with_error(&mysql);
    }
    MYSQL_RES *result;  
    MYSQL_ROW  row;
    result=mysql_store_result(&mysql);
    row=mysql_fetch_row(result);
    //获得申请者的客户端套接字
    int send_fd;
    send_fd=Get_connfd(relation.send);

    //如果没有这两个的信息
    if(row==NULL)
    {
   
        //查看添加好友账户是否存在
        char buf[BUFSIZ];
        sprintf(buf,"select status from account where id=%d",relation.recv);
        printf("buf:%s\n",buf);
        ret=mysql_real_query(&mysql,buf,strlen(buf));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
        MYSQL_RES *result1;  
        MYSQL_ROW  row1;
        result1=mysql_store_result(&mysql);
        row1=mysql_fetch_row(result1);
        if(row1==NULL)
        {
   
            char mes[256];
            sprintf(mes,"账号[%d]不存在",relation.recv);
            Send_pack(send_fd,PRINT_APPLY,mes);
            return;
        }


        //用户存在
        relation.relation=STRANGER;
        memset(buf_t,0,sizeof(buf_t));
        //请求为0
        //表示好友还没验证
        sprintf(buf_t,"insert into friend values('%d','%d','%d','%d')",relation.send,relation.recv,relation.relation,0);
        printf("buf_t:%s\n",buf_t);
        ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
        printf("用户%d对%d发起了好友申请\n",relation.send,relation.recv);

        //获得被申请好友的客户端套接字
        //如果在线
        int recv_fd=Get_connfd(relation.recv);
        printf("hehehheheheh>>>>>>>>>\n");
        printf("recv_fd:%d\n",recv_fd);
        if(recv_fd<0)
        {
   
            printf("所申请的用户[%d]不在线\n",relation.recv);
            Send_pack(send_fd,PRINT_APPLY,"d");
            return;
        }
        else
        {
   
            char str[256];
            sprintf(str,"用户[%d]向你发送了好友请求",relation.send);
            Send_connfd_pack(ADD_FRIEND_APPLY,relation.send,relation.recv,str);

            //如果在线为request为2已经发送
            char buf[BUFSIZ];
            sprintf(buf,"update friend set request=2 where (uid=%d and fid=%d)",relation.send,relation.recv);
            printf("buf=%s\n",buf);
            int ret=mysql_real_query(&mysql,buf,strlen(buf));
            if(ret)
            {
   
                Mysql_with_error(&mysql);
            }
        }
    }
    else if(row!=NULL)
    {
   
        if(atoi(row[0])==0)
        {
   
            char mes[256];
            sprintf(mes,"正在等待对方验证,请不要重复发好友申请");
            Send_pack(send_fd,PRINT_APPLY,mes);
            return;
        }
        if(atoi(row[0])==2)
        {
   
            char mes[256];
            sprintf(mes,"请勿重复添加好友");
            Send_pack(send_fd,PRINT_APPLY,mes);
            return;
        }
    }


}
/*void Add_friend(int fd,char* buf)
{

    Relation_t relation;
    memcpy(&relation,buf,sizeof(relation));
    printf("server/ friend send:%d\n",relation.send);
    printf("server/ friend recv:%d\n",relation.recv);
    printf("server/ friend message:%s\n",relation.message);

    char buf_t[BUFSIZ];
    //查询有没有这两个人的账号
    sprintf(buf_t,"select *from friend where (uid=%d and fid=%d) or (uid=%d and fid=%d)",relation.send,relation.recv,relation.recv,relation.send);
    printf("buf_t:%s\n",buf_t);
    int ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
    if(ret)
    {
        Mysql_with_error(&mysql);
    }
    MYSQL_RES *result;  
    MYSQL_ROW  row;
    result=mysql_store_result(&mysql);
    row=mysql_fetch_row(result);
    //获得申请者的客户端套接字
    int send_fd;
    send_fd=Get_connfd(relation.send);

    //如果没有这两个的信息
    if(row==NULL)
    {
        //
        relation.relation=STRANGER;
        memset(buf_t,0,sizeof(buf_t));
        sprintf(buf_t,"insert into friend values('%d','%d','%d','%d')",relation.send,relation.recv,relation.relation,0);
        printf("buf_t:%s\n",buf_t);
        ret=mysql_real_query(&mysql,buf_t,strlen(buf_t));
        if(ret)
        {
            Mysql_with_error(&mysql);
        }
        printf("用户%d对%d发起了好友申请\n",relation.send,relation.recv);

        //获得被申请好友的客户端套接字
        //如果在线
        int recv_fd=Get_connfd(relation.recv);
        printf("hehehheheheh>>>>>>>>>\n");
        printf("recv_fd:%d\n",recv_fd);
        if(recv_fd<0)
        {
            printf("所申请的用户[%d]不在线\n",relation.recv);
            Send_pack(send_fd,PRINT_APPLY,"d");
            return;
        }
        else
        {
            char str[256];
            sprintf(str,"用户[%d]向你发送了好友请求",relation.send);
            Send_connfd_pack(ADD_FRIEND_APPLY,relation.send,relation.recv,str);

            //如果在线为request为2已经发送
            char buf[BUFSIZ];
            sprintf(buf,"update friend set request=2 where (uid=%d and fid=%d)",relation.send,relation.recv);
            printf("buf=%s\n",buf);
            int ret=mysql_real_query(&mysql,buf,strlen(buf));
            if(ret)
            {
                Mysql_with_error(&mysql);
            }
        }
    }
    else if(row!=NULL)
    {
        Send_pack(send_fd,PRINT_APPLY,"w");
        return;
    }


}*/
void Send_connfd_pack(int flag,int sender,int recver,char* buf)
{
   
    int recv_fd;
    server_list_t pos;
    //获得接受者套接字
    List_ForEach(list_ser,pos)
    {
   
        if(pos->data.id==recver)
        {
   
            printf("该用户的客户端套接字为:%d\n",pos->data.connfd);
            recv_fd=pos->data.connfd;
        }
    }
    int send_fd;
    send_fd=Get_connfd(sender);

    char str[BUFSIZ];
    box_t box;
    box.flag=flag;
    box.sender=sender;//申请者
    box.recver=recver;//被申请者
    box.send_fd=send_fd;//申请者客户端号
    box.recv_fd=recv_fd;//被申请者客户端号

    //buf:用户[%d]向你发送了好友请求
    strcpy(box.message,buf);

    memcpy(str,&box,sizeof(box));

    printf("server send message:%s\n",box.message);
    printf("server send flag:%d\n",box.flag);
    printf("server/ friend send id:%d\n",box.sender);
    printf("server/ friend recv id:%d\n",box.recver);
    //朋友客户端号
    printf("server/ friend recv_fd:%d\n",recv_fd);
    printf("server/ friend send_fd:%d\n",send_fd);

    if(send(recv_fd,str,sizeof(str),0)<0)
    {
   
        my_err("send error!",__LINE__);
    }

}
void Add_friend_accept(int fd,char* buf)
{
   
    Relation_t relation;
    memcpy(&relation,buf,sizeof(relation));
    printf("server/ friend accpet send:%d\n",relation.send);
    printf("server/ friend accpet recv:%d\n",relation.recv);
    printf("server/ friend accpet message:%s\n",relation.message);

    char str1[BUFSIZ];
    char str2[BUFSIZ];
    if(strcmp(relation.message,"y")==0)
    {
   
        char buf[BUFSIZ];
        relation.relation=PAL;
        sprintf(buf,"update friend set status =%d where (uid=%d and fid=%d) ",relation.relation,relation.recv,relation.send);
        printf("buf:%s\n",buf);
        int ret=mysql_real_query(&mysql,buf,strlen(buf));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
        printf("[%d]成为了[%d]的新朋友\n",relation.send,relation.recv);

        sprintf(str1,"[%d]通过了您的好友请求",relation.send);
        Send_pack_name(ADD_FRIEND_ACCEPT_APPLY,relation.send,relation.recv,str1);//发给申请者

        sprintf(str2,"你已经和[%d]成为了朋友",relation.recv);
        Send_pack_name(ADD_FRIEND_ACCEPT_APPLY,relation.recv,relation.send,str2);//发给被申请者
    }
    else
    {
   
        char buf[BUFSIZ];
        sprintf(buf,"delete from friend where (uid=%d and fid=%d)",relation.recv,relation.send);
        printf("buf:%s\n",buf);
        int ret=mysql_real_query(&mysql,buf,strlen(buf));
        if(ret)
        {
   
            Mysql_with_error(&mysql);
        }
        printf("[%d]拒绝成为[%d]的好友\n",relation.send,relation.recv);

        memset(str1,0,sizeof(str1));
        sprintf(str1,"[%d]拒绝了您的好友请求",relation.send);
        Send_pack_name(ADD_FRIEND_ACCEPT_APPLY,relation.send,relation.recv,str1);//发给申请者

    }
}

void Send_pack_name(int flag ,int sender,int recver,char *buf)
{
   
    int recv_fd=Get_connfd(recver);
    char str[BUFSIZ];
    apply_messgae mes;

    mes.flag=flag;
    mes.sender=sender;//被申请者
    mes.recver=recver;//申请者
    strcpy(mes.message,buf);
    printf("server/ friend accept apply send:%d\n",mes.sender);
    printf("server/ friend accept apply recv:%d\n",mes.recver);
    printf("server/ friend accept apply send message:%s\n",mes.message);

    memcpy(str,&mes,sizeof(mes));
    
    printf("server send message:%s\n",mes.message);
    printf("server send flag:%d\n",mes.flag);
    if(send(recv_fd,str,sizeof(str),0)<0)
    {
   
        my_err("send error!",__LINE__);
    }


}
int Get_connfd(int id)
{
   
    server_list_t pos;
    List_ForEach(list_ser,pos)
    {
   
        if(pos->data.id==id)
        {
   
            printf("用户套接字:%d\n",pos->data.connfd);
            return pos->data.connfd;
        }
    }
    return -1;
}

void Del_friend(int fd,char* buf)
{
   
    
    Relation_t relation;
    memcpy(&relation,buf,sizeof(relation));
    printf("server/ friend send:%d\n",relation.send);
    printf("server/ friend recv:%d\n",relation.recv);
    printf</
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值