Linux下C实现的聊天室

来源:互联网 发布:用js写带框99乘法表 编辑:程序博客网 时间:2024/05/16 00:58
实现目标

一个在Linux下可以使用的聊天软件,要求至少实现如下功能:
1. 采用Client/Server架构
2. Client A 登陆聊天服务器前,需要注册自己的ID和密码
3. 注册成功后,Client A 就可以通过自己的ID和密码登陆聊天服务器
4. 多个Client X 可以同时登陆聊天服务器之后,与其他用户进行通讯聊天
5. Client A成功登陆后可以查看当前聊天室内其他在线用户Client x
6. Client A可以选择发消息给某个特定的Client X,即”悄悄话”功能
7. Client A 可以选择发消息全部的在线用户,即”群发消息”功能
8. Client A 在退出时需要保存聊天记录
9. Server端维护一个所有登陆用户的聊天会的记录文件,以便备查
可以选择实现的附加功能:
1. Server可以内建一个特殊权限的账号admin,用于管理聊天室
2. Admin可以将某个Client X “提出聊天室”
3. Admin可以将某个Client X ”设为只能旁听,不能发言”
4. Client 端发言增加表情符号,可以设置某些自定义的特殊组合来表达感情.如输入:),则会自动发送”XXX向大家做了个笑脸”
5. Client段增加某些常用话语,可以对其中某些部分进行”姓名替换”,例如,输入/ClientA/welcome,则会自动发送”ClientA 大侠,欢迎你来到咱们的聊天室”

附加功能:

文件传输

部分主要代码:

客户端:

client_main.h

[cpp] view plain copy
 print?
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <sys/socket.h>  
  5. #include <netinet/in.h>  
  6. #include <netdb.h>  
  7. #include <signal.h>  
  8. #include <sys/ipc.h>  
  9. #include <sys/msg.h>  
  10. #include <string.h>  
  11. #include <errno.h>  
  12. #include <pthread.h>  
  13. #include <sys/types.h>  
  14. #include <fcntl.h>  
  15. #include <sys/stat.h>  
  16. #define PORT 6666  
  17. #define MAXLEN 1000  
  18. #define OK 1  
  19. #define FAULT 0  
  20. struct message    /*消息结构体*/  
  21. {  
  22.     char flag[15];             /*标志位*/  
  23.     char name[20];             /*用户名*/  
  24.     char msg[MAXLEN];          /*消息内容*/  
  25.     char addressee[20];        /*传输文件目的用户*/  
  26.     int size;                  /*传输内容字节数*/  
  27. };  
  28. int qid = -1,fd = -1;  
  29. int sockfd = -1;               /*套接字描述符*/  
  30. int savefilefd = -1;           /*保存文件描述符*/  
  31. char filefromname[20];         /*文件来源名*/  
  32. char chat_log[100];            /*聊天记录名*/  
  33. pthread_mutex_t lock ;         /*线程锁*/  


client_handle.h

[cpp] view plain copy
 print?
  1. #ifndef CLIENT_HANDLE_H  
  2. #define CLIENT_HANDLE_H  
  3.   
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <unistd.h>  
  7. #include <sys/socket.h>  
  8. #include <netinet/in.h>  
  9. #include <signal.h>  
  10. #include <sys/ipc.h>  
  11. #include <sys/msg.h>  
  12. #include <string.h>  
  13. #include <errno.h>  
  14. #include <pthread.h>  
  15. #include <sys/types.h>  
  16. #include <fcntl.h>  
  17. #include <sys/stat.h>  
  18. #define PORT 8888  
  19. #define MAXLEN 1000  
  20. #define OK 1  
  21. #define FAULT 0  
  22. struct message    /*消息结构体*/  
  23. {  
  24.     char flag[15];             /*标志位*/  
  25.     char name[20];             /*用户名*/  
  26.     char msg[MAXLEN];          /*消息内容*/  
  27.     char addressee[20];        /*传输文件目的用户*/  
  28.     int size;                  /*传输内容字节数*/  
  29. };  
  30. extern int qid,fd;  
  31. extern int sockfd;               /*套接字描述符*/  
  32. extern int savefilefd;           /*保存文件描述符*/  
  33. extern char filefromname[20];    /*文件来源名*/  
  34. extern char chat_log[100];       /*聊天记录名*/  
  35. extern pthread_mutex_t lock ;    /*线程锁*/  
  36. char filefromuser[20];           /*文件发送者用户名*/  
  37. char locname[20];                /*本客户端用户名*/  
  38.   
  39. int Interface();  
  40. void cutStr(char str[],char left[], int n, char right[],int m, char c);  
  41. int help(char str[]);  
  42. void expression(char name[],char msg[]);  
  43. void common_use_words(char msg[]);  
  44. void handlesendfile();  
  45. void handlerecvfile(struct message *msg);  
  46. void handlerecvmsg(int *sockfd);  
  47. int admin_kick(int sockfd,struct message *a);  
  48. int admin_screen(int sockfd,struct message *a);  
  49. int login_admin(struct message *a);  
  50. int login_success(struct message *a);  
  51. int Register(struct message *a);  
  52. void log_user(struct message *a);  
  53.   
  54. #endif //CLIENT_HANDLE_H  


my_system_call.h

[cpp] view plain copy
 print?
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <sys/socket.h>  
  5. #include <netinet/in.h>  
  6. #include <netdb.h>  
  7. #include <signal.h>  
  8. #include <sys/ipc.h>  
  9. #include <sys/msg.h>  
  10. #include <string.h>  
  11. #include <errno.h>  
  12. #include <pthread.h>  
  13. #include <sys/types.h>  
  14. #include <fcntl.h>  
  15. #include <sys/stat.h>  

client_main.c

[cpp] view plain copy
 print?
  1. /*************************************************** 
  2. File name: client.c 
  3. Author:Chenchunjian 
  4. Data:2012 
  5. Description:聊天软件客户端main函数 
  6. ***************************************************/  
  7. #include "../../include/client_main.h"  
  8.   
  9. int main(int argc, char *argv[])  
  10. {  
  11.     int ret;  
  12.     int do_number;  
  13.     char str[MAXLEN];  
  14.     char buf[MAXLEN];  
  15.     char buf_new[100];  
  16.     struct message msg;  
  17.     struct message a;  
  18.     struct sockaddr_in my_addr;  
  19.     time_t timep;  
  20.     enum action{log=1,reg,ex};  
  21.     struct hostent *host;  
  22.     if(argc!=2)  
  23.     {  
  24.         fprintf(stderr,"Usage:%s hostname \a\n",argv[0]);  
  25.         exit(1);  
  26.     }  
  27.     if((host=gethostbyname(argv[1]))==NULL)  
  28.     {  
  29.         fprintf(stderr,"Gethostname error\n");  
  30.         exit(1);  
  31.     }  
  32.     while(1)  
  33.     {  
  34.         if((sockfd=my_socket(PF_INET,SOCK_STREAM,0)) < 0)  /*创建套接字,使用TCP协议*/  
  35.         {  
  36.             exit(-1);  
  37.         }  
  38.         bzero(&my_addr,sizeof(struct sockaddr_in));      /*清空地址结构*/  
  39.         my_addr.sin_family = AF_INET;                     /*使用IPV4通信域*/  
  40.         my_addr.sin_port = htons(PORT);                   /*端口号转换为网络字节序*/  
  41.         my_addr.sin_addr = *((struct in_addr *)host->h_addr);      /*可接受任意地址*/  
  42.         if(my_connect(sockfd,(struct sockaddr *)(&my_addr),sizeof(my_addr)) == -1)  /*主动连接服务器*/  
  43.         {  
  44.             printf("正在连接,请稍等……\n");  
  45.             exit(1);  
  46.         }  
  47.         do_number = Interface();     /*登录界面*/  
  48.         switch(do_number)  
  49.         {  
  50.             case log:               /*登录*/  
  51.                 {  
  52.                      int n = 3;  
  53.                      while(n)  
  54.                      {  
  55.                          log_user(&a);  
  56.                          if(my_strcmp(a.msg,"hello,admin!") == 0)    /*管理员登录成功*/  
  57.                          {  
  58.                              if(login_admin(&a) == 0)  
  59.                              {  
  60.                                  return FAULT;  
  61.                              }  
  62.                          }  
  63.                          if(my_strcmp(a.msg,"login,success!") == 0)   /*用户登录成功*/  
  64.                          {  
  65.                             if(login_success(&a) == FAULT)  
  66.                             {  
  67.                                 return FAULT;  
  68.                             }  
  69.                          }  
  70.                          else                                       /*登录未成功*/  
  71.                          {  
  72.                              n--;  
  73.                              printf("你还有 %d次机会!\n",n);  
  74.                          }  
  75.                     }  
  76.                     my_close(sockfd);  
  77.                     exit(3);  
  78.                     break;  
  79.                 }  
  80.             case reg:     /*注册*/  
  81.                 {  
  82.                     Register(&a);  
  83.                     break;  
  84.                 }  
  85.             case ex:      /*退出*/  
  86.                 {  
  87.                     my_close(sockfd);  
  88.                     printf("离开聊天室!\n");  
  89.                     break;  
  90.                 }  
  91.             default:  
  92.                 {  
  93.                     break;  
  94.                 }  
  95.         }  
  96.     }  
  97.     my_close(sockfd);  
  98.     return FAULT;  
  99. }  

admin.c

[cpp] view plain copy
 print?
  1. #include "../../include/client_handle.h"  
  2.   
  3. /*************************************************** 
  4. 函数名:admin_chat 
  5. 功能:管理员聊天功能 
  6. 传入参数:int sockfd,struct message *a 
  7. 返回值:退出返回FAULT 
  8. ***************************************************/  
  9. int admin_chat(int sockfd,struct message *a)    
  10. {  
  11.     char str[MAXLEN];  
  12.     char buf[MAXLEN];  
  13.     time_t timep;  
  14.     sprintf(chat_log,"./chat_log/%s.txt",(*a).name);  
  15.     if((fd=my_open(chat_log,O_RDWR|O_CREAT|O_APPEND,0777)) < 0)  
  16.     {  
  17.         printf("打开聊天记录失败!");  
  18.     exit(1);  
  19.     }  
  20.     setbuf(stdin,NULL);  
  21.     my_strcpy((*a).flag,"all");  
  22.     printf("尊敬的%s你好,如需帮助请输入:.help\n",locname);  
  23.     while(1)  
  24.     {  
  25.         memset((*a).msg,0,strlen((*a).msg));  
  26.         memset(str,0,strlen(str));  
  27.         usleep(100000);  
  28.         printf("TO %s:\n",(*a).flag);  
  29.         setbuf(stdin,NULL);  
  30.         gets(str);  
  31.         if(OK == help(str))                      //提示信息    
  32.         {  
  33.             continue;  
  34.         }  
  35.         my_strcpy((*a).name,locname);  
  36.         my_strcpy(buf,(*a).flag);  
  37.         cutStr(str,(*a).flag,15,(*a).msg,MAXLEN,'$');    //调用字符切割函数    
  38.         expression((*a).name,(*a).msg);               //表情替换函数   
  39.         common_use_words((*a).msg);                    //常用语使用函数  
  40.         if(my_strcmp((*a).flag,"exit") == 0)  
  41.         {  
  42.             return FAULT;  
  43.         }  
  44.         if(my_strcmp((*a).flag,"view") == 0)             
  45.         {  
  46.             my_send(sockfd,a,sizeof((*a)),0);       //请求查看在线用户  
  47.                 my_strcpy((*a).flag,buf);  
  48.             continue;  
  49.         }  
  50.         if(my_strcmp((*a).flag,"all") == 0)  
  51.         {  
  52.             my_send(sockfd,a,sizeof(*a),0);          
  53.             continue;  
  54.         }  
  55.             if ((my_strcmp((*a).flag,"trans") == 0) && (savefilefd <=0))  
  56.         {  
  57.                 if ((my_strcmp((*a).msg,"agree") == 0) && (savefilefd == 0))  
  58.             {  
  59.                 char savefilename[MAXLEN];  
  60.             my_strcpy((*a).addressee,filefromuser);  
  61.             printf("请输入你想保存的文件名:\n");  
  62.             do  
  63.             {  
  64.                 setbuf(stdin,NULL);  
  65.                 gets(savefilename);  
  66.                 savefilefd = open(savefilename,O_RDWR|O_CREAT|O_EXCL,0777);  
  67.                 if(savefilefd == -1)  
  68.                 {  
  69.                     printf("文件已存在,你重新输入:\n");  
  70.                 }  
  71.             }while(savefilefd == -1);  
  72.             if(savefilefd < 0)  
  73.             {  
  74.                 printf("接收文件失败!\n");  
  75.                 savefilefd = -1;  
  76.             }  
  77.             else  
  78.             {  
  79.                 my_strcpy((*a).msg,"agree");  
  80.                 my_send(sockfd,a,sizeof(*a),0);  
  81.                 printf("文件接收中……\n");  
  82.             }  
  83.         }  
  84.             else  
  85.             {  
  86.                 memset(str,0,strlen(str));  
  87.                 cutStr((*a).msg,(*a).addressee,20,str,MAXLEN,'$');  
  88.                 if (str[0] != '\0' && (*a).addressee[0] != '\0')  
  89.                 {  
  90.                     char transfileallname[22];  
  91.                     sprintf(transfileallname,"./%s",str);  
  92.                     savefilefd = open(str,O_RDWR,0666);  
  93.                     if(savefilefd < 0)  
  94.                     {  
  95.                         printf("打开文件失败!\n");  
  96.                         savefilefd = -1;  
  97.                     }  
  98.                     else  
  99.                     {  
  100.                         memset((*a).msg,0,strlen((*a).msg));  
  101.                         my_strcpy((*a).msg,str);  
  102.                         my_send(sockfd,a,sizeof(*a),0);  
  103.                     }  
  104.                 }  
  105.                 else  
  106.                 {  
  107.                     my_strcpy((*a).msg,"disagree");  
  108.                     my_strcpy((*a).name,locname);  
  109.                     my_strcpy((*a).addressee,filefromuser);  
  110.                     my_send(sockfd,a,sizeof(*a),0);  
  111.                 }  
  112.             }  
  113.             my_strcpy((*a).flag,buf);  
  114.             continue;  
  115.         }  
  116.         if (my_strcmp((*a).flag,"trans") == 0)  
  117.         {  
  118.             my_strcpy((*a).flag,buf);  
  119.         }  
  120.         else  
  121.         {  
  122.             my_strcpy(buf,(*a).flag);  
  123.             my_strcpy((*a).addressee,(*a).flag);  
  124.             my_strcpy((*a).flag,"personal");  
  125.             my_send(sockfd,a,sizeof(*a),0);             //发送私信  
  126.             my_strcpy((*a).flag,buf);  
  127.             time (&timep);  
  128.             memset(str,0,strlen(str));  
  129.             sprintf(str,"%s你对 %s 说: %s\n",ctime(&timep),(*a).flag,(*a).msg);  
  130.             printf("%s",str);  
  131.             my_write(fd,str,strlen(str));              //写入聊天记录文件中  
  132.         }  
  133.     }  
  134. }  
  135.   
  136. /*************************************************** 
  137. 函数名:admin_kick 
  138. 功能:管理员替人操作 
  139. 传入参数:int sockfd,struct message *a 
  140. 返回值:成功返回1,否则返回0 
  141. ***************************************************/  
  142. int admin_kick(int sockfd,struct message *a)       
  143. {  
  144.     char str[MAXLEN];   
  145.     do  
  146.     {  
  147.         printf("你想把谁踢出聊天室:\n");  
  148.         setbuf(stdin,NULL);         //清空缓存  
  149.         gets(str);                    
  150.     }while(my_strcmp(str,"admin") == 0);                    
  151.     if(my_strcmp(str,"") == 0)           //str为空  
  152.     {  
  153.         return FAULT;  
  154.     }  
  155.     else  
  156.     {  
  157.         my_strcpy((*a).flag,"admin_kick");            //管理员踢人标志  
  158.         my_strcpy((*a).msg,str);  
  159.         my_send(sockfd,a,sizeof(struct message),0);   //客户端把要求传给服务器         
  160.     }  
  161.     return OK;  
  162. }  
  163. /*************************************************** 
  164. 函数名:admin_screen 
  165. 功能:管理员禁言功能 
  166. 传入参数:int sockfd,struct message *a 
  167. 返回值:成功返回1,否则返回0 
  168. ***************************************************/  
  169. int admin_screen(int sockfd,struct message *a)  
  170. {  
  171.     char str[MAXLEN];  
  172.     do  
  173.     {  
  174.         printf("你想禁言/解禁谁:\n");  
  175.         setbuf(stdin,NULL);  
  176.         gets(str);  
  177.     }while(my_strcmp(str,"admin") == 0);  
  178.     if(my_strcmp(str,"") == 0)   
  179.     {  
  180.         return FAULT;  
  181.     }  
  182.     else  
  183.     {  
  184.         my_strcpy((*a).flag,"admin_screen");        //禁言标志  
  185.         my_strcpy((*a).msg,str);  
  186.         my_send(sockfd,a,sizeof(struct message),0);    
  187.     }  
  188.     return OK;  
  189. }  
  190. /*************************************************** 
  191. 函数名:login_admin 
  192. 功能:管理员登录 
  193. 传入参数:struct message *a 
  194. 返回值:成功返回1,否则返回0 
  195. ***************************************************/  
  196. int login_admin(struct message *a)  
  197. {  
  198.     int do_number;                        
  199.     pthread_t pid;  
  200.     memset((*a).msg,0,strlen((*a).msg));                              //清空消息  
  201.     my_strcpy(chat_log,"admin");                                          //聊天记录名  
  202.     pthread_create(&pid,NULL,(void*)handlerecvmsg,(void *)&sockfd);     //创建线程      
  203.     while(1)  
  204.     {  
  205.         usleep(500000);  
  206.         do  
  207.         {  
  208.             printf("1.踢人  2.禁言/解禁  3.查看在线用户  4.聊天  5.退出\n");  
  209.             printf("please input:\n");         
  210.             setbuf(stdin,NULL);                                 //清空缓存  
  211.             scanf(" %d",&do_number);  
  212.             system("clear");  
  213.             setbuf(stdin,NULL);                                 //清空缓存  
  214.         }while((do_number != 1) && (do_number != 2) && (do_number != 3) && (do_number != 4)&& (do_number != 5));  
  215.         switch(do_number)  
  216.         {  
  217.             case 1:  
  218.             {  
  219.                 admin_kick(sockfd,a);                 
  220.                 break;  
  221.             }  
  222.             case 2:  
  223.             {  
  224.                 admin_screen(sockfd,a);         
  225.                 break;  
  226.             }  
  227.             case 3:  
  228.             {  
  229.                 my_strcpy((*a).flag,"view");  
  230.                 my_send(sockfd,a,sizeof(*a),0);  
  231.                 break;  
  232.             }  
  233.             case 4:  
  234.             {  
  235.                 admin_chat(sockfd,a);  
  236.                 break;  
  237.             }  
  238.             case 5:  
  239.             {  
  240.                 my_close(sockfd);  
  241.                 return FAULT;  
  242.             }  
  243.             default:  
  244.             {  
  245.                 break;  
  246.             }  
  247.         }  
  248.     }  
  249.     return OK;  
  250. }  


handlefile.c

[cpp] view plain copy
 print?
  1. #include "../../include/client_handle.h"  
  2.   
  3.   
  4. /*************************************************** 
  5. 函数名:handlerecvfile 
  6. 功能:文件接收 
  7. 传入参数:struct message *msg 
  8. 返回值:无 
  9. ***************************************************/  
  10. void handlerecvfile(struct message *msg)  
  11. {  
  12.     int n;  
  13.     struct message recvmsg = *msg;  
  14.     if(my_strcmp(recvmsg.msg,"end$") == 0)           //接收标志为end$  
  15.     {  
  16.         printf("文件传输结束!\n");  
  17.         my_close(savefilefd);  
  18.         savefilefd = -1;  
  19.         return ;  
  20.     }  
  21.     else  
  22.     {  
  23.         pthread_mutex_lock(&lock);           //上锁  
  24.         n=my_write(savefilefd,recvmsg.msg,recvmsg.size); //写入文件,保存聊天记录  
  25.         pthread_mutex_unlock(&lock);   //解琐  
  26.         if(n < recvmsg.size && n > 0)  
  27.         {  
  28.             printf("接收文件出错!\n");  
  29.         return ;  
  30.         }  
  31.         }  
  32.     return ;  
  33. }  
  34.   
  35. /*************************************************** 
  36. 函数名:handlesendfile 
  37. 功能:文件传输 
  38. 传入参数:无 
  39. 返回值:无 
  40. ***************************************************/  
  41. void handlesendfile()  
  42. {  
  43.   
  44.     struct message filedata;  
  45.     do  
  46.     {  
  47.         memset(filedata.msg,0,sizeof(filedata.msg));            //清空消息缓存      
  48.         filedata.size =read(savefilefd,filedata.msg,1000);        
  49.         my_strcpy(filedata.flag,"transf");  
  50.         my_strcpy(filedata.addressee,filefromname);  
  51.         if (filedata.size == 0)  
  52.         {  
  53.             printf("文件传输完毕!\n");  
  54.             my_strcpy(filedata.msg,"end$");  
  55.             my_send(sockfd,&filedata,sizeof(struct message),0);     //向服务器发送结束标志  
  56.         }  
  57.         else if (filedata.size > 0)  
  58.         {  
  59.             my_send(sockfd,&filedata,sizeof(struct message),0);     //发送文件数据      
  60.             usleep(100000);                
  61.         }  
  62.         else  
  63.         {  
  64.             printf("读取文件失败,文件传输中止\n");  
  65.             break;  
  66.         }  
  67.     }while(filedata.size > 0);  
  68.     my_close(savefilefd);  
  69.     savefilefd = -1 ;  
  70. }  


handlerecvmsg.c
[cpp] view plain copy
 print?
  1. #include "../../include/client_handle.h"  
  2.   
  3. /*************************************************** 
  4. 函数名:handlerecvmsg 
  5. 功能:消息接收 
  6. 传入参数:int *sockfd 
  7. 返回值:无 
  8. ***************************************************/  
  9. void handlerecvmsg(int *sockfd)  
  10. {  
  11.     int connfd = *sockfd;  
  12.     int nread;  
  13.     char buf[1024];  
  14.     char str[1024];  
  15.     struct message recvmsg;  
  16.     time_t timep;                              //显示当前时间  
  17.     if((fd=my_open(chat_log,O_RDWR|O_CREAT|O_APPEND,0777)) < 0)          //创建聊天记录文件      
  18.     {  
  19.         printf("打开聊天记录失败!");  
  20.         exit(1);  
  21.     }  
  22.     while(1)  
  23.     {  
  24.         nread = my_recv(connfd,&recvmsg,sizeof(struct message),0);    //接受文件       
  25.         if(nread == 0)  
  26.         {  
  27.             printf("You have detached from the server!\n");       
  28.             my_close(fd);  
  29.             my_close(connfd);  
  30.             exit(0);  
  31.         }  
  32.         else if (my_strcmp(recvmsg.flag,"all") == 0)             //接受群发信息  
  33.         {  
  34.             time (&timep);  
  35.         memset(str,0,strlen(str));  
  36.             sprintf(str,"%s%s 对大家说: %s\n",ctime(&timep),recvmsg.name,recvmsg.msg);  
  37.         printf("%s",str);  
  38.         my_write(fd,str,strlen(str));                          //聊天信息写入文件  
  39.         }  
  40.         else if (my_strcmp(recvmsg.flag,"personal") == 0)         //接受私信   
  41.         {  
  42.             time (&timep);  
  43.         memset(str,0,strlen(str));  
  44.             sprintf(str,"%s%s 对你说: %s\n",ctime(&timep),recvmsg.name,recvmsg.msg);  
  45.         printf("%s",str);  
  46.         my_write(fd,str,strlen(str));                         //保存聊天记录  
  47.         }  
  48.     else if (my_strcmp(recvmsg.flag,"sermsg") == 0)          //系统提示信息  
  49.         {  
  50.             time (&timep);  
  51.         memset(str,0,strlen(str));  
  52.             sprintf(str,"%s系统信息: %s\n",ctime(&timep),recvmsg.msg);  
  53.         printf("%s",str);  
  54.         my_write(fd,str,strlen(str));  
  55.         continue;  
  56.         }  
  57.         else if (my_strcmp(recvmsg.flag,"view") == 0)       //收到查看在线用户标志  
  58.         {  
  59.             time (&timep);  
  60.         memset(str,0,strlen(str));  
  61.             sprintf(str,"%s在线用户:\n%s\n",ctime(&timep),recvmsg.msg);  
  62.         printf("%s",str);  
  63.             continue;  
  64.         }  
  65.         else if (my_strcmp(recvmsg.flag,"trans") == 0)          //传输文件标志  
  66.         {  
  67.             pthread_t pid;  
  68.             if (my_strcmp(recvmsg.msg,"agree") == 0)          //同意接受文件标志  
  69.             {  
  70.                 my_strcpy(filefromname,recvmsg.name);  
  71.         printf("文件传送中……\n");  
  72.                 //创建线程发送文件  
  73.                 pthread_create(&pid,NULL,(void *)handlesendfile,NULL);     //创建发送文件线程  
  74.             }  
  75.             else if(my_strcmp(recvmsg.msg,"disagree") == 0)  
  76.             {  
  77.                 printf("对方拒绝接收文件\n");  
  78.                 my_close(savefilefd);  
  79.                 savefilefd = -1;  
  80.             }  
  81.             else if(my_strcmp(recvmsg.msg,"noexist") == 0)  
  82.             {  
  83.                 printf("对不起,该客户端不存在\n");  
  84.                 my_close(savefilefd);  
  85.                 savefilefd = -1;  
  86.             }  
  87.             else  
  88.             {  
  89.                 my_strcpy(filefromuser,recvmsg.name);  
  90.                 my_strcpy(filefromname,recvmsg.msg);  
  91.                 printf("%s向你传文件%s,是否同意接受?\n同意请输入:trans$agree\t不同意请输入:trans$disagree\n",recvmsg.name,recvmsg.msg);  
  92.                 savefilefd = 0;  
  93.             }  
  94.             continue;  
  95.         }  
  96.         else if(my_strcmp(recvmsg.flag,"transf") == 0)                 
  97.         {  
  98.             pthread_t pid_transf;  
  99.         pthread_create(&pid_transf,NULL,(void *)handlerecvfile,&recvmsg); //创建文件传输线程  
  100.         pthread_join(pid_transf,NULL);            
  101.             continue;  
  102.         }  
  103.         else  
  104.         {  
  105.             if(my_strcmp(recvmsg.flag,"") == 0)  
  106.             {  
  107.                 continue;  
  108.             }  
  109.         }  
  110.     }  
  111. }  


handlestr.c

[cpp] view plain copy
 print?
  1. #include "../../include/client_handle.h"  
  2.   
  3. /*************************************************** 
  4. 函数名:cutStr 
  5. 功能:将字符串str在字符c处分割,前后两段 
  6. 分别赋给left和right,left最大长度为n,str最大 
  7. 长度为max 
  8. 传入参数:char str[],char left[], int n, char right[],int max, char c 
  9. 返回值:无 
  10. ***************************************************/  
  11. void cutStr(char str[],char left[], int n, char right[],int max, char c)  
  12. {  
  13.     int i,k,j;  
  14.     for(i = 0 ; i < n ;i++)  
  15.     {  
  16.         if(str[i] == c)                             //c为str的分割符  
  17.         break;  
  18.     }  
  19.     if(i == n)  
  20.     {  
  21.         i = -1;  
  22.     }  
  23.     else  
  24.     {  
  25.         memset(left,0,strlen(left));  
  26.         for(k = 0 ; k < i ; k++)  
  27.         {  
  28.             left[k] = str[k];         //c左边的字符串赋给left[]   
  29.         }  
  30.     }  
  31.     for(j = i+1 ; j < max;j++)  
  32.     {  
  33.         if(str[j] == '\0')  
  34.         break;  
  35.         right[j-i-1] = str[j];     //c右边的字符串给right[]  
  36.     }  
  37.     left[i] = '\0';  
  38.     if(j < max)  
  39.     {  
  40.         right[j-i-1] = '\0';  
  41.     }     
  42.     else  
  43.     {  
  44.         right[max] = '\0';  
  45.     }  
  46. }  
  47.   
  48. /*************************************************** 
  49. 函数名:common_use_words 
  50. 功能:常用语替换 
  51. 传入参数:char msg[] 
  52. 返回值:无 
  53. ***************************************************/  
  54. void common_use_words(char msg[])  
  55. {  
  56.     int i=0,j=0;  
  57.     char common[MAXLEN];  
  58.     char tmp[MAXLEN];  
  59.     if(msg[0] == '/')  
  60.     {  
  61.         my_strcpy(tmp,msg);  
  62.         memset(msg,0,strlen(msg));  
  63.         for(i=1;i<MAXLEN;i++)  
  64.         {  
  65.             if(tmp[i] != '/')  
  66.             {  
  67.                 msg[i-1] = tmp[i];  
  68.             }  
  69.             else  
  70.             {  
  71.                 break;  
  72.             }  
  73.         }  
  74.         msg[i-1] = ',';  
  75.         msg[i] = '\0';  
  76.         i++;  
  77.         for(j=0;i<MAXLEN;i++,j++)  
  78.         {  
  79.             if(tmp[i] != '\0')  
  80.             {  
  81.                 common[j] = tmp[i];  
  82.             }  
  83.             else  
  84.             {  
  85.             break;  
  86.             }  
  87.         }  
  88.         common[j] = '\0';  
  89.         if(my_strcmp(common,"welcome") == 0)  
  90.         {  
  91.             strcat(msg,"欢迎来到我们的聊天室^_^");         //连接字符串  
  92.             return ;  
  93.         }  
  94.         strcat(msg,common);  
  95.           
  96.     }  
  97. }  
  98. /*************************************************** 
  99. 函数名:expression 
  100. 功能:常用表情替换 
  101. 传入参数:char name[],char msg[],int m 
  102. 返回值:无 
  103. ***************************************************/  
  104. void expression(char name[],char msg[])  
  105. {  
  106.     if(my_strcmp(msg,":)") == 0)  
  107.     {  
  108.         sprintf(msg,"%s 做了个笑脸!",name);  
  109.     }  
  110.     if(my_strcmp(msg,":(") == 0)  
  111.     {  
  112.         sprintf(msg,"%s 表情很沮丧!",name);  
  113.     }  
  114.     if(my_strcmp(msg,"囧") == 0)  
  115.     {  
  116.         sprintf(msg,"%s 表情很囧!",name);  
  117.     }  
  118.     if(my_strcmp(msg,"哈哈") == 0)  
  119.     {  
  120.         sprintf(msg,"哈哈 ^_^");  
  121.     }  
  122.     if(my_strcmp(msg,"汗") == 0)  
  123.     {  
  124.         sprintf(msg,"~_~|||");  
  125.     }  
  126.     if(my_strcmp(msg,"晕") == 0)  
  127.     {  
  128.         sprintf(msg,"@_@");  
  129.     }  
  130. }  


interface.c
[cpp] view plain copy
 print?
  1. #include "../../include/client_handle.h"  
  2. /*************************************************** 
  3. 函数名:Interface 
  4. 功能:登录界面 
  5. 传入参数:无 
  6. 返回值:无 
  7. ***************************************************/  
  8. int Interface()  
  9. {  
  10.     int do_number;  
  11.     do  
  12.     {  
  13.         system("clear");  
  14.         printf("----------------------------------\n");  
  15.         printf("        欢迎进入聊天室   \n");  
  16.         printf("       1.登录                 \n");  
  17.         printf("       2.注册               \n");  
  18.         printf("       3.退出               \n");  
  19.         printf("----------------------------------\n");  
  20.         printf("请选择:\n");  
  21.         setbuf(stdin,NULL);  
  22.         scanf(" %d",&do_number);  
  23.         setbuf(stdin,NULL);  
  24.     }while((do_number != 1) && (do_number != 2) && (do_number != 3));  
  25.     return do_number;  
  26. }  
  27. /*************************************************** 
  28. 函数名:help 
  29. 功能:帮助 
  30. 传入参数:char str[] 
  31. 返回值:成功返回1,否则返回0 
  32. ***************************************************/  
  33. int help(char str[])  
  34. {  
  35.     if(my_strcmp(str,".help") == 0)  
  36.     {  
  37.         printf("尊敬的%s用户,你好:\n",locname);  
  38.         printf("all$hello!-------------对所有人说hello!\n");  
  39.         printf("bill$hello!------------对bill说hello!\n");  
  40.         printf("trans$bill$hello.txt---传文件hello.txt给bill\n");  
  41.         printf("trans$agree------------同意接收文件\n");  
  42.         printf("trans$disagree---------不同意接收文件\n");  
  43.         printf("view$------------------查看在线用户\n");  
  44.         printf("exit$------------------退出\n");                   
  45.         return OK;  
  46.     }  
  47.     else  
  48.     {  
  49.         return FAULT;  
  50.     }  
  51. }  


log.c
[cpp] view plain copy
 print?
  1. #include "../../include/client_handle.h"  
  2.   
  3. /*************************************************** 
  4. 函数名:log_user 
  5. 功能:用户登录 
  6. 传入参数:struct message *a 
  7. 返回值:无 
  8. ***************************************************/  
  9. void log_user(struct message *a)  
  10. {  
  11.     do  
  12.     {  
  13.         printf("请输入用户名(10字以内):\n");  
  14.         memset((*a).name,0,strlen((*a).name));  
  15.         scanf("%s",(*a).name);  
  16.         my_strcpy(locname,(*a).name);  
  17.         printf("请输入密码(20位以内):\n");  
  18.         memset((*a).msg,0,strlen((*a).msg));  
  19.         scanf("%s",(*a).msg);  
  20.     }while(strlen((*a).name)>20 || strlen((*a).msg)>20);  
  21.     my_strcpy((*a).flag,"login");  
  22.     my_send(sockfd,a,sizeof(*a),0);                 //向服务器发送登录信息  
  23.     printf("正在登录,请稍等……\n");  
  24.     my_recv(sockfd,a,sizeof(*a),0);  
  25.     printf("recv the message from server:%s\n",(*a).msg);  
  26. }  
  27. /*************************************************** 
  28. 函数名:login_success 
  29. 功能:登录成功进入聊天模式 
  30. 传入参数:struct message *a 
  31. 返回值:退出返回0,否则返回1 
  32. ***************************************************/  
  33. int login_success(struct message *a)  
  34. {  
  35.     char str[MAXLEN];  
  36.     char buf[MAXLEN];  
  37.     time_t timep;  
  38.     pthread_t pid;  
  39.     sprintf(chat_log,"./chat_log/%s.txt",(*a).name);  
  40.     if((fd=my_open(chat_log,O_RDWR|O_CREAT|O_APPEND,0777)) < 0)  
  41.     {  
  42.         printf("打开聊天记录失败!");  
  43.     exit(1);  
  44.     }  
  45.     pthread_create(&pid,NULL,(void*)handlerecvmsg,(void *)&sockfd);         //创建接受消息线程  
  46.     setbuf(stdin,NULL);  
  47.     my_strcpy((*a).flag,"all");  
  48.     printf("尊敬的%s你好,如需帮助请输入:.help\n",locname);  
  49.     while(1)  
  50.     {  
  51.         memset((*a).msg,0,strlen((*a).msg));  
  52.         memset(str,0,strlen(str));  
  53.         usleep(100000);  
  54.         printf("TO %s:\n",(*a).flag);  
  55.         setbuf(stdin,NULL);  
  56.         gets(str);  
  57.         if(OK == help(str))                      //提示信息    
  58.         {  
  59.             continue;  
  60.         }  
  61.         my_strcpy((*a).name,locname);  
  62.         my_strcpy(buf,(*a).flag);  
  63.         cutStr(str,(*a).flag,15,(*a).msg,MAXLEN,'$');    //调用字符切割函数    
  64.         expression((*a).name,(*a).msg);               //表情替换函数   
  65.         common_use_words((*a).msg);                    //常用语使用函数  
  66.         if(my_strcmp((*a).flag,"exit") == 0)  
  67.         {  
  68.             return FAULT;  
  69.         }  
  70.         if(my_strcmp((*a).flag,"view") == 0)             
  71.         {  
  72.             my_send(sockfd,a,sizeof((*a)),0);       //请求查看在线用户  
  73.                 my_strcpy((*a).flag,buf);  
  74.             continue;  
  75.         }  
  76.         if(my_strcmp((*a).flag,"all") == 0)  
  77.         {  
  78.             my_send(sockfd,a,sizeof(*a),0);          
  79.             continue;  
  80.         }  
  81.             if ((my_strcmp((*a).flag,"trans") == 0) && (savefilefd <=0))  
  82.         {  
  83.                 if ((my_strcmp((*a).msg,"agree") == 0) && (savefilefd == 0))  
  84.             {  
  85.                 char savefilename[MAXLEN];  
  86.             my_strcpy((*a).addressee,filefromuser);  
  87.             printf("请输入你想保存的文件名:\n");  
  88.             do  
  89.             {  
  90.                 setbuf(stdin,NULL);  
  91.                 gets(savefilename);  
  92.                 savefilefd = open(savefilename,O_RDWR|O_CREAT|O_EXCL,0777);  
  93.                 if(savefilefd == -1)  
  94.                 {  
  95.                     printf("文件已存在,你重新输入:\n");  
  96.                 }  
  97.             }while(savefilefd == -1);  
  98.             if(savefilefd < 0)  
  99.             {  
  100.                 printf("接收文件失败!\n");  
  101.                 savefilefd = -1;  
  102.             }  
  103.             else  
  104.             {  
  105.                 my_strcpy((*a).msg,"agree");  
  106.                 my_send(sockfd,a,sizeof(*a),0);  
  107.                 printf("文件接收中……\n");  
  108.             }  
  109.         }  
  110.             else  
  111.             {  
  112.                 memset(str,0,strlen(str));  
  113.                 cutStr((*a).msg,(*a).addressee,20,str,MAXLEN,'$');  
  114.                 if (str[0] != '\0' && (*a).addressee[0] != '\0')  
  115.                 {  
  116.                     char transfileallname[22];  
  117.                     sprintf(transfileallname,"./%s",str);  
  118.                     savefilefd = open(str,O_RDWR,0666);  
  119.                     if(savefilefd < 0)  
  120.                     {  
  121.                         printf("打开文件失败!\n");  
  122.                         savefilefd = -1;  
  123.                     }  
  124.                     else  
  125.                     {  
  126.                         memset((*a).msg,0,strlen((*a).msg));  
  127.                         my_strcpy((*a).msg,str);  
  128.                         my_send(sockfd,a,sizeof(*a),0);  
  129.                     }  
  130.                 }  
  131.                 else  
  132.                 {  
  133.                     my_strcpy((*a).msg,"disagree");  
  134.                     my_strcpy((*a).name,locname);  
  135.                     my_strcpy((*a).addressee,filefromuser);  
  136.                     my_send(sockfd,a,sizeof(*a),0);  
  137.                 }  
  138.             }  
  139.             my_strcpy((*a).flag,buf);  
  140.             continue;  
  141.         }  
  142.         if (my_strcmp((*a).flag,"trans") == 0)  
  143.         {  
  144.             my_strcpy((*a).flag,buf);  
  145.         }  
  146.         else  
  147.         {  
  148.             my_strcpy(buf,(*a).flag);  
  149.             my_strcpy((*a).addressee,(*a).flag);  
  150.             my_strcpy((*a).flag,"personal");  
  151.             my_send(sockfd,a,sizeof(*a),0);             //发送私信  
  152.             my_strcpy((*a).flag,buf);  
  153.             time (&timep);  
  154.             memset(str,0,strlen(str));  
  155.             sprintf(str,"%s你对 %s 说: %s\n",ctime(&timep),(*a).flag,(*a).msg);  
  156.             printf("%s",str);  
  157.             my_write(fd,str,strlen(str));              //写入聊天记录文件中  
  158.         }  
  159.     }  
  160.     return OK;  
  161. }  


register.c

[cpp] view plain copy
 print?
  1. #include "../../include/client_handle.h"  
  2.   
  3. /*************************************************** 
  4. 函数名:Register 
  5. 功能:注册 
  6. 传入参数:struct message *a 
  7. 返回值:返回0 
  8. ***************************************************/  
  9. int Register(struct message *a)  
  10. {  
  11.     char password_t[MAXLEN];  
  12.     do  
  13.     {  
  14.         printf("请输入用户名(10字以内):\n");  
  15.         memset((*a).name,0,strlen((*a).name));  
  16.         setbuf(stdin,NULL);  
  17.         scanf("%s",(*a).name);  
  18.     }while(strlen((*a).name)>20);  
  19.     while(1)  
  20.     {  
  21.         printf("请输入密码(20位以内):\n");  
  22.         memset((*a).msg,0,strlen((*a).msg));  
  23.         setbuf(stdin,NULL);  
  24.         scanf("%s",(*a).msg);  
  25.         printf("请再次输入密码(20位以内):\n");  
  26.         memset(password_t,0,strlen(password_t));  
  27.         setbuf(stdin,NULL);  
  28.         scanf("%s",password_t);  
  29.         if(my_strcmp((*a).msg,password_t) != 0 || strlen((*a).msg)>20 || strlen(password_t)>20)  
  30.         {  
  31.             printf("密码出错!\n");  
  32.         }  
  33.         else  
  34.         {  
  35.             break;  
  36.         }  
  37.     }  
  38.     my_strcpy((*a).flag,"reg");  
  39.     my_send(sockfd,a,sizeof(*a),0);  
  40.     printf("正在注册,请稍等……\n");  
  41.     my_recv(sockfd,a,sizeof(*a),0);  
  42.     printf("recv the message from server:%s\n",(*a).msg);  
  43.     sleep(3);  
  44. }  




服务器:

check.h

[cpp] view plain copy
 print?
  1. #include <fcntl.h>  
  2. #include <sys/stat.h>  
  3. #include <stdlib.h>  
  4. #include <stdio.h>  
  5. #include <unistd.h>  
  6. #include <sys/types.h>  
  7. #include <sys/socket.h>  
  8. #include <netinet/in.h>  
  9. #include <string.h>  
  10. #include <pthread.h>  
  11. #include <string.h>  
  12. #include <sqlite3.h>  
  13. #define MAXLEN 1000  
  14. #define REG_OK 1  
  15. #define REG_FAULT 0  
  16. #define LOG_USER 0  
  17. #define LOG_ADMIN 1  
  18. #define LOG_FAULT -1  
  19. struct message    /*消息结构体*/  
  20. {  
  21.     char flag[15];             /*标志位*/  
  22.     char name[20];             /*用户名*/  
  23.     char msg[MAXLEN];          /*消息内容*/  
  24.     char addressee[20];        /*传输文件目的用户*/  
  25.     int size;                  /*传输内容字节数*/  
  26. };  
  27.   
  28. int reg_check(struct message *recievemsg);  
  29. int login_check(struct message *recievemsg);  




linklist.h

[cpp] view plain copy
 print?
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <unistd.h>  
  5. #include <sys/socket.h>  
  6. #include <errno.h>  
  7. #include <netinet/in.h>  
  8. #include <pthread.h>  
  9. typedef struct _clientinf       /*用户结构体*/  
  10. {  
  11.     char name[20];              /*用户名*/  
  12.     struct sockaddr_in addr_in; /*地址*/  
  13.     int decr;                   /*socket文件描述符*/  
  14.     pthread_t pid;              /*线程号*/  
  15.     int speak;                  /*禁言标志*/  
  16. }clientinf;  
  17. typedef clientinf datatype;  
  18. typedef struct _LNode           /*在线链表结构体*/  
  19. {  
  20.     datatype data;  
  21.     struct _LNode * next;  
  22. }LNode,*LinkList;  
  23. extern LinkList CreateLinkList(void);  
  24. extern void deletelist(LinkList L ,datatype e);  
  25. extern void insertend(LinkList L,datatype e);  
  26. extern void DisplayList(LinkList L);  

server.h
[cpp] view plain copy
 print?
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include <errno.h>  
  4. #include <string.h>  
  5. #include <netdb.h>  
  6. #include <sys/types.h>  
  7. #include <netinet/in.h>  
  8. #include <sys/socket.h>  
  9. #include <unistd.h>  
  10. #include <arpa/inet.h>  
  11. #include <ctype.h>  
  12. #include "linklist.h"  
  13. #include "check.h"  
  14. #define MAXLEN 1000  
  15. #define portnumber 6666  /* 宏定义端口号 */  
  16. #define MAX_LINE 80  
  17. LinkList clientlink;  


check.c

[cpp] view plain copy
 print?
  1. #include "../../include/check.h"  
  2.   
  3. /*************************************************** 
  4. 函数名:reg_check 
  5. 功能:注册检查 
  6. 传入参数:struct message *recievemsg 
  7. 返回值:成功REG_OK,失败REG_FAULT 
  8. ***************************************************/  
  9. int reg_check(struct message *recievemsg)  
  10. {  
  11.     int fd;  
  12.     int read_size,write_size;  
  13.     struct message cmpmsg;  
  14.     char *p_name;  
  15.     char *p_passwore;  
  16.     int rc,i,ncols;  
  17.     sqlite3 *db;  
  18.     sqlite3_stmt *stmt;  
  19.     char sql[128] ;  
  20.     const char *tail;  
  21.     if(strlen(recievemsg->name)>20 || strlen(recievemsg->msg)>20 )  
  22.     {  
  23.         return REG_FAULT;  
  24.     }  
  25.     if(my_strcmp(recievemsg->name,"admin")==0)  
  26.     {  
  27.         return REG_FAULT;  
  28.     }  
  29.     if(my_strcmp(recievemsg->name,"all")==0)  
  30.     {  
  31.         return REG_FAULT;  
  32.     }  
  33.     if(my_strcmp(recievemsg->name,"reg")==0)  
  34.     {  
  35.         return REG_FAULT;  
  36.     }  
  37.     if(my_strcmp(recievemsg->name,"login")==0)  
  38.     {  
  39.         return REG_FAULT;  
  40.     }  
  41.     if(my_strcmp(recievemsg->name,"trans")==0)  
  42.     {  
  43.         return REG_FAULT;  
  44.     }  
  45.     /*打开数据库*/  
  46.     rc = sqlite3_open("./src/db/chat.db",&db);  
  47.     if(rc)  
  48.     {   
  49.          fprintf(stderr,"can't open databse:%s",sqlite3_errmsg(db));  
  50.          sqlite3_close(db);  
  51.          return REG_FAULT;  
  52.     }        
  53.     /*检查重名退出*/  
  54.     memset(sql,0,sizeof(sql));  
  55.     sprintf(sql,"select * from member where name='%s';",(recievemsg->name));  
  56.     rc = sqlite3_prepare(db,sql,strlen(sql),&stmt,&tail);  
  57.     if(rc != SQLITE_OK)  
  58.     {  
  59.             fprintf(stderr,"SQLerror:%s",sqlite3_errmsg(db));  
  60.     }  
  61.       /*执行*/  
  62.      rc = sqlite3_step(stmt);  
  63.      ncols = sqlite3_column_count(stmt);  
  64.      while (rc == SQLITE_ROW)  
  65.      {  
  66.          rc = sqlite3_step(stmt);  
  67.   
  68.          sqlite3_finalize(stmt);  
  69.          sqlite3_close(db);  
  70.          return REG_FAULT;  
  71.      }  
  72.       /*销毁stmt*/  
  73.     sqlite3_finalize(stmt);  
  74.     /*注册*/    
  75.     memset(sql,0,sizeof(sql));  
  76.     sprintf(sql,"insert into member (name,password) values(?,?);");  
  77.     rc = sqlite3_prepare(db,sql,strlen(sql),&stmt,&tail);  
  78.     if(rc != SQLITE_OK)  
  79.     {  
  80.         fprintf(stderr,"SQLerror:%s",sqlite3_errmsg(db));  
  81.     }  
  82.     p_name = recievemsg->name;  
  83.     sqlite3_bind_text(stmt,1,p_name,strlen(p_name),NULL);  
  84.     p_passwore = recievemsg->msg;  
  85.     sqlite3_bind_text(stmt,2,p_passwore,strlen(p_passwore),NULL);    
  86.     rc = sqlite3_step(stmt);  
  87.     sqlite3_finalize(stmt);  
  88.   
  89.       /*关闭数据库*/  
  90.       sqlite3_close(db);  
  91.       return REG_OK;  
  92. }  
  93.   
  94.   
  95. /*************************************************** 
  96. 函数名:login_check 
  97. 功能:注册检查 
  98. 传入参数:struct message *recievemsg 
  99. 返回值:管理员admin成功LOG_ADMIN, 
  100. 普通用户成功LOG_USER,失败LOG_FAULT 
  101. ***************************************************/  
  102. int login_check(struct message *recievemsg)  
  103. {  
  104.     int fd;  
  105.     int read_size,write_size;  
  106.     struct message cmpmsg;  
  107.     char *p_name;  
  108.     char *p_passwore;  
  109.     int rc,i,ncols;  
  110.     sqlite3 *db;  
  111.     sqlite3_stmt *stmt;  
  112.     char sql[128] ;  
  113.     const char *tail;  
  114.       
  115.     /*打开数据库*/  
  116.     rc = sqlite3_open("./src/db/chat.db",&db);       
  117.     if(rc)  
  118.     {   
  119.          fprintf(stderr,"can't open databse:%s",sqlite3_errmsg(db));  
  120.          sqlite3_close(db);  
  121.          return LOG_FAULT;  
  122.     }        
  123.     /*检查用户名密码*/  
  124.     memset(sql,0,sizeof(sql));  
  125.     sprintf(sql,"select * from member where name='%s' and password='%s';",(recievemsg->name),(recievemsg->msg));  
  126.     rc = sqlite3_prepare(db,sql,strlen(sql),&stmt,&tail);  
  127.     if(rc != SQLITE_OK)  
  128.     {  
  129.             fprintf(stderr,"SQLerror:%s",sqlite3_errmsg(db));  
  130.     }  
  131.       /*执行*/  
  132.      rc = sqlite3_step(stmt);  
  133.      ncols = sqlite3_column_count(stmt);  
  134.      while (rc == SQLITE_ROW)  
  135.      {  
  136.              rc = sqlite3_step(stmt);  
  137.              sqlite3_finalize(stmt);  
  138.              sqlite3_close(db);  
  139.              if(strcmp(recievemsg->name,"admin") == 0)  
  140.              {  
  141.                  return LOG_ADMIN;  
  142.              }  
  143.              else  
  144.              {  
  145.                  return LOG_USER;  
  146.              }  
  147.   
  148.      }  
  149.       /*销毁stmt*/  
  150.     sqlite3_finalize(stmt);  
  151.       /*关闭数据库*/  
  152.     sqlite3_close(db);  
  153.     return LOG_FAULT;  
  154. }  


server.c

[cpp] view plain copy
 print?
  1. #include "../../include/server.h"  
  2.   
  3. /*************************************************** 
  4. 函数名:main 
  5. 功能:聊天软件服务器 
  6. 传入参数:void 
  7. 返回值:int 
  8. ***************************************************/  
  9. int main(void)  
  10. {  
  11.     int re;  
  12.     int fd;  
  13.     struct message a;  
  14.     datatype e;  
  15.     LinkList transfileNode;  
  16.     char buf[MAXLEN],str[MAXLEN];  
  17.     time_t timep;  
  18.     clientinf clientNode;  
  19.     clientNode.speak = 1;  
  20.     my_strcpy(clientNode.name,"***");  
  21.     clientlink=CreateLinkList();  
  22.     if((fd=my_open("./chat_log_server/chat_log_server.txt",O_RDWR|O_CREAT|O_APPEND,0777)) < 0)  
  23.     {  
  24.         printf("failure to open chat_log_server!");  
  25.         exit(1);  
  26.     }  
  27.     int lfd;  
  28.     int cfd;  
  29.     int sfd;  
  30.     int rdy;  
  31.     struct sockaddr_in sin;  
  32.     struct sockaddr_in cin;  
  33.     int client[FD_SETSIZE];  /* 客户端连接的套接字描述符数组 */  
  34.     int maxi;  
  35.     int maxfd;                        /* 最大连接数 */  
  36.     fd_set rset;  
  37.     fd_set allset;  
  38.     socklen_t addr_len;         /* 地址结构长度 */  
  39.     char buffer[MAX_LINE];  
  40.     int i;  
  41.     int n;  
  42.     int len;  
  43.     int opt = 1;   /* 套接字选项 */  
  44.     char addr_p[20];  
  45.     /* 对server_addr_in  结构进行赋值  */  
  46.     bzero(&sin,sizeof(struct sockaddr_in));   /* 先清零 */  
  47.     sin.sin_family=AF_INET;  
  48.     sin.sin_addr.s_addr=htonl(INADDR_ANY);  //表示接受任何ip地址   将ip地址转换成网络字节序  
  49.     sin.sin_port=htons(portnumber);         //将端口号转换成网络字节序  
  50.     /* 调用socket函数创建一个TCP协议套接口 */  
  51.     if((lfd=my_socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:IPV4;SOCK_STREAM:TCP  
  52.     {  
  53.         fprintf(stderr,"Socket error:%s\n\a",strerror(errno));  
  54.         exit(1);  
  55.     }  
  56.     /*设置套接字选项 使用默认选项*/  
  57.     my_setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  
  58.     /* 调用bind函数 将serer_addr结构绑定到sockfd上  */  
  59.     if(my_bind(lfd,(struct sockaddr *)(&sin),sizeof(struct sockaddr))==-1)  
  60.     {  
  61.         fprintf(stderr,"Bind error:%s\n\a",strerror(errno));  
  62.         exit(1);  
  63.     }  
  64.     /* 开始监听端口   等待客户的请求 */  
  65.     if(my_listen(lfd,20)==-1)  
  66.     {  
  67.         fprintf(stderr,"Listen error:%s\n\a",strerror(errno));  
  68.         exit(1);  
  69.     }  
  70.     printf("正在连接.......\n");  
  71.   
  72.     maxfd = lfd;      /*对最大文件描述符进行初始化*/  
  73.     maxi = -1;  
  74.     /*初始化客户端连接描述符集合*/  
  75.     for(i = 0;i < FD_SETSIZE;i++)  
  76.     {  
  77.         client[i] = -1;  
  78.     }  
  79.     FD_ZERO(&allset);                     /* 清空文件描述符集合 */  
  80.     FD_SET(lfd,&allset);                 /* 将监听字设置在集合内 */  
  81.     /* 开始服务程序的死循环 */  
  82.     while(1)  
  83.     {  
  84.         rset = allset;  
  85.         /*得到当前可以读的文件描述符数*/  
  86.         rdy = select(maxfd + 1, &rset, NULL, NULL, NULL);  
  87.         if(FD_ISSET(lfd, &rset))  
  88.         {  
  89.             addr_len = sizeof(sin);  
  90.   
  91.             /* 接受客户端的请求 */  
  92.             if((cfd=my_accept(lfd,(struct sockaddr *)(&cin),&addr_len))==-1)  
  93.             {  
  94.                 fprintf(stderr,"Accept error:%s\n\a",strerror(errno));  
  95.                 exit(1);  
  96.             }  
  97.             /*查找一个空闲位置*/  
  98.             for(i = 0; i<FD_SETSIZE; i++)  
  99.             {  
  100.                 if(client[i] <= 0)  
  101.                 {  
  102.                     client[i] = cfd;   /* 将处理该客户端的连接套接字设置到该位置 */  
  103.                     break;  
  104.                 }  
  105.             }  
  106.             /* 太多的客户端连接   服务器拒绝俄请求  跳出循环 */  
  107.             if(i == FD_SETSIZE)  
  108.             {  
  109.                 printf("too many clients");  
  110.                 exit(1);  
  111.             }  
  112.             FD_SET(cfd, &allset);     /* 设置连接集合 */  
  113.             if(cfd > maxfd)                  /* 新的连接描述符 */  
  114.             {  
  115.                 maxfd = cfd;  
  116.             }  
  117.             if(i > maxi)  
  118.             {  
  119.                 maxi = i;  
  120.             }  
  121.             if(--rdy <= 0)                /* 减少一个连接描述符 */  
  122.             {  
  123.                 continue;  
  124.             }  
  125.         }  
  126.         /* 对每一个连接描述符做处理 */  
  127.         for(i = 0;i< FD_SETSIZE;i++)  
  128.         {  
  129.             if((sfd = client[i]) < 0)  
  130.             {  
  131.                 continue;  
  132.             }  
  133.   
  134.             if(FD_ISSET(sfd, &rset))  
  135.             {  
  136.                 /*如果没有可以读的套接字   退出循环*/  
  137.                 if(--rdy < 0)  
  138.                 {  
  139.                     break;  
  140.                 }  
  141.                 re = my_recv(sfd,&a,sizeof(a)+1,0);  
  142.                 clientNode.decr = sfd;  
  143.                 my_strcpy(clientNode.name,a.name);  
  144.                 if(re == 0)                                /*客户端断开连接*/  
  145.                 {  
  146.                     server_exit(&a, &clientNode) ;  
  147.                     fflush(stdout);                                    /* 刷新 输出终端 */  
  148.                     my_close(sfd);  
  149.                     FD_CLR(sfd, &allset);                        /*清空连接描述符数组*/  
  150.                     client[i] = -1;  
  151.                 }  
  152.                 else  
  153.                 {  
  154.                     if(my_strcmp(a.flag,"login") == 0)      /*客户端请求登录*/  
  155.                     {  
  156.                         if(overlap(a) == 0)               /*若该用户名不在线*/  
  157.                         {  
  158.                             server_login(&a,&clientNode);    /*处理登录请求*/  
  159.                         }  
  160.                         else                                 /*若该用户名已在线*/  
  161.                         {  
  162.                             strcpy(a.msg,"overlap");  
  163.                             my_send(clientNode.decr,&a,sizeof(struct message),0);/*返回重名提示*/  
  164.                         }  
  165.                         continue;  
  166.                     }  
  167.                     else if(my_strcmp(a.flag,"reg") == 0)   /*客户端请求注册*/  
  168.                     {  
  169.                         server_reg(&a,&clientNode);       /*处理注册请求*/  
  170.                         continue;  
  171.                     }  
  172.                     else if (my_strcmp(a.flag,"all") == 0)    /*客户端请求广播*/  
  173.                     {  
  174.                         if(server_all(&a,&clientNode) == 1)   /*处理广播请求*/  
  175.                         {  
  176.                             memset(str,0,strlen(str));  
  177.                             time (&timep);  
  178.                             sprintf(str,"%s%s TO %s: %s\n",ctime(&timep),a.name,a.flag,a.msg);  
  179.                             printf("%s",str);  
  180.                             my_write(fd,str,strlen(str));      /*将广播写入聊天记录*/  
  181.                         }  
  182.                         continue;  
  183.                     }  
  184.                     else if(my_strcmp(a.flag,"personal") == 0)  /*客户端请求私聊*/  
  185.                     {  
  186.                         if(server_personal(&a,&clientNode) == 1) /*处理私聊请求*/  
  187.                         {  
  188.                             memset(str,0,strlen(str));  
  189.                             time (&timep);  
  190.                             sprintf(str,"%s%s TO %s: %s\n",ctime(&timep),a.name,a.addressee,a.msg);  
  191.                             printf("%s",str);  
  192.                             my_write(fd,str,strlen(str));       /*将私聊写入聊天记录*/  
  193.                         }  
  194.                     }  
  195.                     else if(my_strcmp(a.flag,"view") == 0)    /*客户端请求查看在线用户*/  
  196.                     {  
  197.                         server_view(&a,&clientNode);        /*处理查看在线用户请求*/  
  198.                         continue;  
  199.                     }  
  200.                     else if(my_strcmp(a.flag,"admin_kick") == 0) /*管理员替人请求*/  
  201.                     {  
  202.                         int closefd;  
  203.                         closefd = server_admin_kick(&a,&clientNode);  /*处理管理员替人请求*/  
  204.                         FD_CLR(closefd, &allset);                      /*清空连接描述符数组*/  
  205.                         int j;  
  206.                         for(j = 0;j< FD_SETSIZE;j++)  
  207.                         {  
  208.                             if(closefd == client[j])  
  209.                             {  
  210.                                 client[j]=-1;  
  211.                                 break;  
  212.                             }  
  213.                         }  
  214.                         continue;  
  215.                     }  
  216.                     else if(my_strcmp(a.flag,"admin_screen") == 0)/*管理员禁言请求*/  
  217.                     {  
  218.                         server_admin_screen(&a,&clientNode);/*处理管理员禁言请求*/  
  219.                         continue;  
  220.                     }  
  221.                     else if(my_strcmp(a.flag,"trans") == 0) /*客户端文件传输请求*/  
  222.                     {  
  223.   
  224.                         server_trans(&a,&clientNode);    /*处理客户端文件传输请求*/  
  225.                         continue;  
  226.                     }  
  227.                     else if(my_strcmp(a.flag,"transf") == 0) /*客户端文件数据传输请求*/  
  228.                     {  
  229.                         server_transf(&a);        /*传送文件*/  
  230.                         continue;  
  231.                     }  
  232.                 }  
  233.             }  
  234.         }  
  235.     }  
  236.     close(lfd);  
  237.     return 0;  
  238. }  


server_admin.c
[cpp] view plain copy
 print?
  1. #include "../../include/server_handle.h"  
  2.   
  3. /*************************************************** 
  4. 函数名:server_admin_kick 
  5. 功能:处理管理员踢人功能 
  6. 传入参数:struct message *a, clientinf *clientNode 
  7. 返回值:成功返回踢出客户端的fd,否则返回0 
  8. ***************************************************/  
  9. int server_admin_kick(struct message *a, clientinf *clientNode)  
  10. {  
  11.     int closefd;  
  12.     datatype e;  
  13.     my_strcpy(e.name,(*a).msg);  
  14.     LinkList L;  
  15.     L = (LinkList)findlist(clientlink,e);  
  16.     if(L == NULL)  
  17.     {  
  18.         my_strcpy((*a).flag,"sermsg");  
  19.         sprintf((*a).msg,"该用户不在线\n");  
  20.         my_send((*clientNode).decr,a,sizeof(struct message),0);  
  21.         return 0;  
  22.     }  
  23.     else  
  24.     {  
  25.         closefd=L->data.decr;  
  26.         my_close(closefd);  
  27.         deletelist(clientlink,e);  
  28.         L = clientlink;  
  29.         L = L->next;  
  30.         my_strcpy((*a).flag,"sermsg");  
  31.         sprintf((*a).msg,"%s 被管理员踢出了聊天室!",(*a).msg);  
  32.         while(L != NULL)  
  33.         {  
  34.             my_send(L->data.decr,a,sizeof(struct message),0);  
  35.             L = L->next;  
  36.         }  
  37.     }     
  38.     return closefd;  
  39. }  
  40.   
  41. /*************************************************** 
  42. 函数名:server_admin_screen 
  43. 功能:处理管理员禁言功能 
  44. 传入参数:struct message *a, clientinf *clientNode 
  45. 返回值:成功返回1,否则返回0 
  46. ***************************************************/  
  47. int server_admin_screen(struct message *a, clientinf *clientNode)  
  48. {  
  49.     datatype e;  
  50.     my_strcpy(e.name,(*a).msg);  
  51.     LinkList L;  
  52.     L = (LinkList)findlist(clientlink,e);  
  53.     if(L == NULL)  
  54.     {  
  55.          my_strcpy((*a).flag,"sermsg");  
  56.          sprintf((*a).msg,"该用户不在线\n");  
  57.          my_send((*clientNode).decr,a,sizeof(struct message),0);  
  58.          return 0;  
  59.     }  
  60.     else  
  61.     {  
  62.         L->data.speak = (L->data.speak+1)%2;  
  63.         my_strcpy((*a).flag,"sermsg");  
  64.         if(L->data.speak == 0)  
  65.         {  
  66.             sprintf((*a).msg,"%s 被管理员禁言了!",(*a).msg);  
  67.         }  
  68.         else  
  69.         {  
  70.             sprintf((*a).msg,"%s 被管理员解禁!",(*a).msg);  
  71.         }  
  72.         L = clientlink;  
  73.         L = L->next;  
  74.         while(L != NULL)  
  75.         {  
  76.             my_send(L->data.decr,a,sizeof(struct message),0);  
  77.             L = L->next;  
  78.         }  
  79.     }  
  80.     return 1;  
  81. }  


server_chat.c

[cpp] view plain copy
 print?
  1. #include "../../include/server_handle.h"  
  2. /*************************************************** 
  3. 函数名:server_all 
  4. 功能:处理客户端群发消息 
  5. 传入参数:struct message *a, clientinf *clientNode 
  6. 返回值:禁言返回0,否则返回1 
  7. ***************************************************/  
  8. int server_all(struct message *a, clientinf *clientNode)  
  9. {  
  10.   
  11.     datatype e;  
  12.     my_strcpy(e.name,(*a).name);  
  13.     LinkList L;  
  14.     L = (LinkList)findlist(clientlink,e);  
  15.     if(L != NULL)  
  16.     {  
  17.         if(L->data.speak == 0)  
  18.         {  
  19.             my_strcpy((*a).flag,"sermsg");  
  20.             sprintf((*a).msg,"对不起,你已经被管理员禁言了!");  
  21.             my_send(L->data.decr,a,sizeof(struct message),0);  
  22.             return 0;  
  23.         }  
  24.     }  
  25.     if (my_strcmp((*a).msg,"") != 0)  
  26.     {  
  27.         L = clientlink;  
  28.         L = L->next;  
  29.         my_strcpy((*a).name,(*clientNode).name);  
  30.         while(L != NULL)  
  31.         {  
  32.             my_send(L->data.decr,a,sizeof(struct message),0);  
  33.             L = L->next;  
  34.         }  
  35.     }  
  36.     return 1;  
  37. }  
  38. /*************************************************** 
  39. 函数名:server_personal 
  40. 功能:处理客户端私聊 
  41. 传入参数:struct message *a, clientinf *clientNode 
  42. 返回值:成功返回1,否则返回0 
  43. ***************************************************/  
  44. int server_personal(struct message *a, clientinf *clientNode)  
  45. {  
  46.     datatype e;  
  47.     my_strcpy(e.name,(*a).name);  
  48.     LinkList L;  
  49.     L = (LinkList)findlist(clientlink,e);  
  50.     if(L != NULL)  
  51.     {  
  52.         if(L->data.speak == 0)  
  53.         {  
  54.             my_strcpy((*a).flag,"sermsg");  
  55.             sprintf((*a).msg,"对不起,你已经被管理员禁言了!");  
  56.             my_send(L->data.decr,a,sizeof(struct message),0);  
  57.             return 0;  
  58.         }  
  59.     }  
  60.     L = clientlink;  
  61.     L=L->next;  
  62.     my_strcpy(e.name,(*a).addressee);  
  63.     L = (LinkList)findlist(clientlink,e);  
  64.     if(L == NULL)  
  65.     {  
  66.         my_strcpy((*a).flag,"sermsg");  
  67.         sprintf((*a).msg,"该用户不在线\n");  
  68.         my_send((*clientNode).decr,a,sizeof(struct message),0);  
  69.         return 0;  
  70.     }  
  71.     else  
  72.     {  
  73.         if (my_strcmp((*a).msg,"") != 0)  
  74.         {  
  75.             my_send(L->data.decr,a,sizeof(struct message),0);  
  76.         }  
  77.     }  
  78.     return 1;  
  79. }  

server_login_exit.c
[cpp] view plain copy
 print?
  1. #include "../../include/server_handle.h"  
  2. /*************************************************** 
  3. 函数名:overlap 
  4. 功能:重名用户检查 
  5. 传入参数:struct message a 
  6. 返回值:重名返回1,否则返回0 
  7. ***************************************************/  
  8. int overlap(struct message a)  
  9. {  
  10.     LinkList L;  
  11.     L = clientlink->next;  
  12.     while(L != NULL)  
  13.     {  
  14.         if(my_strcmp(L->data.name,a.name) == 0)  
  15.         {  
  16.             return 1;  
  17.         }  
  18.         else  
  19.         {  
  20.             L = L->next;  
  21.         }  
  22.     }  
  23.     return 0;  
  24. }  
  25.   
  26. /*************************************************** 
  27. 函数名:server_login 
  28. 功能:处理客户端登录 
  29. 传入参数:struct message *a, clientinf *clientNode 
  30. 返回值:无 
  31. ***************************************************/  
  32. int server_login(struct message *a, clientinf *clientNode)  
  33. {  
  34.     int i;  
  35.     char buf[MAXLEN];  
  36.     i = login_check(a);  
  37.     if(i == 1)  
  38.     {  
  39.         printf("管理员admin登录成功!\n");  
  40.         my_strcpy((*a).msg,"hello,admin!");  
  41.         my_strcpy((*clientNode).name,(*a).name);  
  42.         insertend(clientlink,*clientNode);  
  43.         my_send((*clientNode).decr,a,sizeof(struct message),0);  
  44.     }  
  45.     else  
  46.     {  
  47.         if(i == 0)  
  48.         {  
  49.             printf("%s 登录成功!\n",(*a).name);  
  50.             memset((*a).msg,0,strlen((*a).msg));  
  51.             my_strcpy((*a).msg,"login,success!");  
  52.             my_strcpy((*clientNode).name,(*a).name);  
  53.             insertend(clientlink,*clientNode);  
  54.             my_send((*clientNode).decr,a,sizeof(struct message),0);  
  55.               
  56.             LinkList L;  
  57.             L = clientlink;  
  58.             L=L->next;  
  59.             my_strcpy((*a).flag,"sermsg");  
  60.             sprintf((*a).msg,"欢迎 %s 进入聊天室!",(*a).name);  
  61.             while(L != NULL)  
  62.             {  
  63.                 my_send(L->data.decr,a,sizeof(struct message),0);  
  64.                 L = L->next;  
  65.             }  
  66.         }  
  67.         else  
  68.         {  
  69.             printf("%s 登录失败!\n",(*a).name);  
  70.             my_strcpy((*a).msg,"login,failure!");  
  71.             my_send((*clientNode).decr,a,sizeof(struct message),0);  
  72.         }  
  73.     }  
  74. }  
  75.   
  76. /*************************************************** 
  77. 函数名:server_exit 
  78. 功能:处理客户端与服务器断开连接 
  79. 传入参数:struct message *a, clientinf *clientNode 
  80. 返回值:无 
  81. ***************************************************/  
  82. int server_exit(struct message *a, clientinf *clientNode)     
  83. {  
  84.     LinkList L;  
  85.     L = clientlink->next;  
  86.     while(L != NULL)  
  87.     {  
  88.         if(L->data.decr == (*clientNode).decr)  
  89.         {                         
  90.             my_strcpy((*clientNode).name,L->data.name);  
  91.             break;  
  92.         }  
  93.         else  
  94.         {  
  95.             L = L->next;  
  96.         }  
  97.     }  
  98.     my_strcpy((*a).flag,"sermsg");  
  99.     printf("%s 离开聊天室\n",(*clientNode).name);  
  100.     deletelist(clientlink ,(*clientNode));  
  101.     L = clientlink;  
  102.     L=L->next;  
  103.     sprintf((*a).msg,"%s 离开聊天室",(*clientNode).name);  
  104.     while(L != NULL)  
  105.     {  
  106.         my_send(L->data.decr,a,sizeof(struct message),0);  
  107.         L = L->next;  
  108.     }  
  109. }  

server_reg.c
[cpp] view plain copy
 print?
  1. #include "../../include/server_handle.h"  
  2. /*************************************************** 
  3. 函数名:server_reg 
  4. 功能:客户端注册处理 
  5. 传入参数:struct message *a, clientinf *clientNode 
  6. 返回值:无 
  7. ***************************************************/  
  8. int server_reg(struct message *a, clientinf *clientNode)  
  9. {  
  10.     int i;  
  11.     char buf[MAXLEN];  
  12.     i = reg_check(a);  
  13.     if(i == 1)  
  14.     {  
  15.         printf("%s 注册成功!\n",(*a).name);  
  16.         my_strcpy((*a).msg,"register,success!");  
  17.         my_strcpy((*clientNode).name,(*a).name);  
  18.         my_send((*clientNode).decr,a,sizeof(struct message),0);  
  19.     }  
  20.     else  
  21.     {  
  22.         printf("%s 登录失败!\n",(*a).name);  
  23.         my_strcpy((*a).msg,"register,failure!");  
  24.         my_send((*clientNode).decr,a,sizeof(struct message),0);  
  25.     }  
  26. }  

server_trans.c
[cpp] view plain copy
 print?
  1. #include "../../include/server_handle.h"  
  2. /*************************************************** 
  3. 函数名:server_trans 
  4. 功能:处理传输文件请求 
  5. 传入参数:struct message *a,clientinf *clientNode 
  6. 返回值:无 
  7. ***************************************************/  
  8. void server_trans(struct message *a,clientinf *clientNode)  
  9. {  
  10.     LinkList L;  
  11.     L = clientlink;  
  12.     L=L->next;  
  13.     while(L != NULL)  
  14.     {  
  15.         if (my_strcmp(L->data.name,(*a).addressee)== 0)  
  16.         {  
  17.             break;  
  18.         }  
  19.         L = L->next;  
  20.     }  
  21.     if(L == NULL)  
  22.     {  
  23.         my_strcpy((*a).msg,"noexist");  
  24.         my_send((*clientNode).decr,a,sizeof(struct message),0);  
  25.         return ;  
  26.     }  
  27.   
  28.     L = clientlink;  
  29.     L=L->next;  
  30.     while(L != NULL)  
  31.     {  
  32.         if (my_strcmp(L->data.name,(*a).name)== 0)  
  33.         {  
  34.             break;  
  35.         }  
  36.         L = L->next;  
  37.     }  
  38.     if(L == NULL)  
  39.     {  
  40.         my_strcpy((*a).msg,"noexist");  
  41.         my_send((*clientNode).decr,a,sizeof(struct message),0);  
  42.     }  
  43.     else  
  44.     {  
  45.         L = clientlink->next;  
  46.         while(L != NULL)  
  47.         {  
  48.             if(my_strcmp(L->data.name,(*a).addressee) == 0)  
  49.             {                      
  50.                 break;  
  51.             }  
  52.             else  
  53.             {  
  54.                 L = L->next;  
  55.             }  
  56.         }  
  57.         my_send(L->data.decr,a,sizeof(struct message),0);  
  58.     }  
  59. }  
  60.   
  61. /*************************************************** 
  62. 函数名:server_transf 
  63. 功能:传输文件数据 
  64. 传入参数:struct message *a 
  65. 返回值:无 
  66. ***************************************************/  
  67. void server_transf(struct message *a)  
  68. {  
  69.     LinkList L;  
  70.     L = clientlink->next;  
  71.     while(L != NULL)  
  72.     {  
  73.         if(my_strcmp(L->data.name,(*a).addressee) == 0)  
  74.         {                         
  75.             break;  
  76.         }  
  77.         else  
  78.         {  
  79.             L = L->next;  
  80.         }  
  81.     }  
  82.     my_send(L->data.decr,a,sizeof(struct message),0);  
  83. }  

server_view.c
[cpp] view plain copy
 print?
  1. #include "../../include/server_handle.h"  
  2. /*************************************************** 
  3. 函数名:server_view 
  4. 功能:处理客户端查看当前在线用户 
  5. 传入参数:struct message *a, clientinf *clientNode 
  6. 返回值:无 
  7. ***************************************************/  
  8. int server_view(struct message *a, clientinf *clientNode)  
  9. {  
  10.     char str[MAXLEN],buf[MAXLEN];  
  11.     LinkList L;  
  12.     int i = 1;  
  13.     L = clientlink;  
  14.     L=L->next;  
  15.     memset(buf,0,strlen(buf));  
  16.     while(L != NULL)  
  17.     {  
  18.         memset(str,0,strlen(str));  
  19.         if(L->data.speak==1)  
  20.         {  
  21.             sprintf(str,"%d. %s (在线)\n",i,L->data.name);  
  22.             my_strcat(buf,str);  
  23.         }  
  24.         else  
  25.         {  
  26.             sprintf(str,"%d. %s (禁言)\n",i,L->data.name);  
  27.             my_strcat(buf,str);  
  28.         }  
  29.         L = L->next;  
  30.         i++;  
  31.     }  
  32.     my_strcpy((*a).name,(*clientNode).name);  
  33.     my_strcpy((*a).msg,buf);  
  34.     my_send((*clientNode).decr,a,sizeof(struct message),0);  
  35. }  
0 0
原创粉丝点击