首页 > 代码库 > Linux 下 c 语言 聊天软件

Linux 下 c 语言 聊天软件

这是我学C语言写的第一个软件,是一个完整的聊天软件,里面包括客户端,和服务器端,可以互现聊天,共享文件,有聊天室等,是一个有TCP和UDP协议的聊天软件,测试过很多次在CENTOS和UBUNTU下都通过,写的简单,但五脏俱全,全部贴出来不保留。运行不了,发信给我,还有个使用指南,我是法语写的,有时间我再写个中文的贴上去。废话不说了,代码来了。

 

  1. #ifndef CHATHEAD_H_
  2. #define CHATHEAD_H_
  3. #include        <arpa/inet.h>
  4. #include        <dirent.h>
  5. #include        <fcntl.h>
  6. #include        <netdb.h>
  7. #include        <unistd.h>
  8. #include        <errno.h>      
  9. #include        <string.h>
  10. #include        <stdio.h>
  11. #include        <stdarg.h>
  12. #include        <signal.h>
  13. #include        <stdlib.h>
  14. #include        <time.h>  
  15. #include        <arpa/inet.h>
  16. #include        <netinet/in.h>   
  17. #include        <sys/uio.h>             
  18. #include        <sys/socket.h>  
  19. #include        <sys/shm.h> 
  20. #include        <sys/sem.h>
  21. #include        <sys/stat.h>
  22. #include        <sys/time.h>       
  23. #include        <sys/types.h>  
  24. #include        <sys/wait.h> 
  25. #define MAXLINE     8000
  26. #ifndef ASTRING_STRUCT
  27. struct aString{
  28.     char string[200];
  29. };
  30. #endif
  31. #ifndef HAVE_MESSAGE_STRUCT
  32. struct chatMessage{
  33.   int           statu;          
  34.   char          type[20],message[1024],contenu[4000];       
  35. };
  36. #endif
  37. #ifndef HAVE_bind_STRUCT
  38. struct chatBind{
  39.      char       ip[50],nom[20],salon[20];
  40.      long int   port;   
  41.      int        id_socket;
  42.             
  43. };
  44. #endif
  45. #ifndef HAVE_bind_STRUCT
  46. struct chatInfo{
  47.     struct  sockaddr_in     cliaddr;
  48.     int                     socket  ;
  49. };
  50. #endif
  51. static void
  52. err_doit(int errnoflag, int error, const char *fmt, va_list ap)
  53. {
  54.     char    buf[MAXLINE];
  55.    vsnprintf(buf, MAXLINE, fmt, ap);
  56.    if (errnoflag)
  57.        snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s",
  58.          strerror(error));
  59.    strcat(buf, "/n");
  60.    fflush(stdout);     /* in case stdout and stderr are the same */
  61.    fputs(buf, stderr);
  62.    fflush(NULL);       /* flushes all stdio output streams */
  63. }
  64. void
  65. err_sys(const char *fmt, ...)
  66. {
  67.     va_list ap;
  68.     va_start(ap, fmt);
  69.     err_doit(1, errno, fmt, ap);
  70.     va_end(ap);
  71.     exit(1);
  72. }
  73.     
  74. void
  75. err_quit(const char *fmt, ...)
  76. {
  77.     va_list     ap;
  78.     va_start(ap, fmt);
  79.     err_doit(0, errno, fmt, ap);
  80.     va_end(ap);
  81.     exit(1);
  82. }
  83. #endif /*CHATHEAD_H_*/

上面的是头文件,服务器和客户端都要用的。

 

  1. #include        "chathead.h"
  2. char * host_name = "127.0.0.255";
  3. int port = 6789;
  4. //struct ip_mreq command; 
  5. struct ip_mreqn command;
  6. int loop = 1;
  7. int iter = 0;
  8. int sin_len;
  9. char message[256];
  10. int socket_descriptor;
  11. struct sockaddr_in sin;
  12. struct hostent *server_host_name;
  13. static int sockfd;
  14. static FILE *fp;
  15. struct aString as[30];
  16. int ignoreList(char *string){
  17.     
  18.     int i;
  19.     
  20.     for(i=0;i<30;i++){
  21.         //printf("_____/n");
  22.         //printf("string %s list %s resultat %d/n",string,as[i].string,strcmp(string,as[i].string)==0);
  23.         if(strcmp(string,as[i].string)==0){
  24.             return -1;
  25.             break;
  26.         }       
  27.     }
  28.     
  29.     return 0;
  30. }
  31. void getMyFichePartage(char *pList){
  32.     
  33.     DIR             *pdir;
  34.     struct dirent   *pent;
  35.     
  36.     strcpy(pList,"");
  37.     
  38.     if((pdir=opendir("./partage"))==NULL)
  39.     {
  40.         fprintf(stderr,"open dir failed./n");
  41.     }
  42.     while(1){
  43.         pent=readdir(pdir);
  44.         if(pent==NULL)break;
  45.         strcat(pList,"/n");
  46.         strcat(pList,pent->d_name);     
  47.         //fprintf(stderr,"%5d %s/n",pent->d_ino,pent->d_name);
  48.     }
  49.     closedir(pdir);
  50.     
  51. }
  52. void delectIgnore(char *p){
  53.     
  54.     int i;
  55.     for(i=0;i<29;i++){
  56.         
  57.         if (strcmp(as[i].string,p)==0){
  58.             strcpy(as[i].string,"");
  59.             printf("UN IGNORE OK./n");
  60.         }
  61.         //else{
  62.         //  printf("PAS TROUVE./n");
  63.         //}
  64.     }
  65. }
  66. void *copyto(void *arg){
  67.     
  68.     char                sendline[MAXLINE];
  69.     struct chatMessage  cm;
  70.     int                 source;
  71.     register int        k;
  72.     char                buf[4000];
  73.     int i=0;
  74.     
  75.     
  76.     while (fgets(sendline,MAXLINE,fp)!=NULL) {      
  77.         
  78.         sscanf(sendline,"%10[^:]:%200[^:]:%200[^/n]",cm.type,cm.message,cm.contenu);
  79.         cm.statu=1;
  80.         
  81.         if(strcmp(cm.type, "UNIGNORE")==0){
  82.             delectIgnore(cm.message);
  83.         
  84.         }else if(strcmp(cm.type, "IGNORE")==0){
  85.             printf("IGNORE OK/n");
  86.             memcpy(as[i].string,cm.message,sizeof(struct aString));
  87.             i=i+1;
  88.         }else if(strcmp(cm.type, "FILE")==0){
  89.             
  90.             if((source=open(cm.contenu,O_RDONLY))<0){
  91.                 perror("Problem sur le source");
  92.             
  93.             }else{
  94.             
  95.                 lseek(source,O_WRONLY,-1);
  96.                 write(sockfd,&cm,sizeof(cm));
  97.                 
  98.                 while((k=read(source,buf,sizeof(buf)))>0){
  99.                     sleep(1);
  100.                      strcpy(cm.contenu,buf);
  101.                      strcpy(cm.type,"FILELINE");
  102.                       
  103.                      printf("type est %s/n",cm.type);
  104.                      printf("contenu est %s/n",cm.contenu);
  105.                      
  106.                      
  107.                      write(sockfd,&cm,sizeof(cm));
  108.                 }
  109.                 printf("ENVOYER FICHE EST TERMINE/n");
  110.                 close(source);  
  111.             }       
  112.                 
  113.         }else{
  114.             
  115.             write(sockfd, &cm, sizeof(cm));
  116.         }   
  117.     }
  118.         shutdown(sockfd,SHUT_WR);
  119.         return(NULL);       
  120. }
  121. void *udpListen(void){
  122.     
  123.     //------udp-------------------------------
  124.         while(1){    
  125.         sin_len = sizeof(sin); 
  126.         if(recvfrom(socket_descriptor, message, 256, 0,(struct sockaddr *)&sin, &sin_len) == -1) { 
  127.              perror("recvfrom");   
  128.         }  
  129.         printf("SERVEUR:%s/n", message);
  130.         sleep(1);   
  131.         } 
  132.         if(setsockopt(socket_descriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP, &command, sizeof(command)) < 0) { 
  133.         // perror("setsockopt:IP_DROP_MEMBERSHIP"); 
  134.          
  135.    }   
  136.     //----------------------------------------
  137. }
  138. void str_cli(FILE *fp_arg, int sockfd_arg)
  139. {
  140.     pthread_t           tid;
  141.     pthread_t           udp;
  142.     struct chatMessage  recvChat,returnMsg;
  143.     int                 target;
  144.     char                nameFile[1024];
  145.     char                myListFichier[1024];
  146.     int                 source;
  147.     char                nomDefiche[1024];
  148.     register int        k;
  149.     char                buf[4000];
  150.     
  151.     sockfd=sockfd_arg;
  152.     fp=fp_arg;
  153.     
  154.     returnMsg.statu=1;
  155.     
  156.     pthread_create(&tid,NULL,copyto,NULL);
  157.     pthread_create(&udp,NULL,udpListen,NULL);
  158.     
  159.     
  160.     while (read(sockfd,&recvChat,sizeof(recvChat))==0){ 
  161.         printf("SERVER SHUTDOWN/n");
  162.         exit (-4);
  163.     }
  164.     while (read(sockfd,&recvChat,sizeof(recvChat))>0){ 
  165.         
  166.         
  167.             if(strcmp(recvChat.type, "TELEFILE")==0){
  168.                 
  169.                 printf("Le utilisateur [%s] a telecharge la ficher [%s]./n",recvChat.message,recvChat.contenu);
  170.                 
  171.                 strcpy(nomDefiche,"./partage/");
  172.                 strcat(nomDefiche,recvChat.contenu);
  173.         
  174.             if((source=open(nomDefiche,O_RDONLY))<0){
  175.                 perror("Problem sur le source");
  176.             
  177.             }else{
  178.             
  179.                 lseek(source,O_WRONLY,-1);
  180.                 
  181.                 strcpy(returnMsg.type,"FILE");
  182.                 strcpy(returnMsg.message,recvChat.message);
  183.                 strcpy(returnMsg.contenu,recvChat.contenu);
  184.                 
  185.                 write(sockfd,&returnMsg,sizeof(returnMsg));
  186.                 
  187.                 while((k=read(source,buf,sizeof(buf)))>0){
  188.                     sleep(1);
  189.                      strcpy(returnMsg.contenu,buf);
  190.                      strcpy(returnMsg.type,"FILELINE");
  191.                                  
  192.                      write(sockfd,&returnMsg,sizeof(returnMsg));
  193.                 }
  194.                 printf("ENVOYER FICHE EST TERMINE/n");
  195.                 close(source);  
  196.             }   
  197.             
  198.             }
  199.         
  200.                                         
  201.             if(strcmp(recvChat.type, "GETLIST")==0){
  202.                 getMyFichePartage(myListFichier);
  203.                 //printf("myListFichier == %s/n",myListFichier);
  204.                 printf("Le utilisateur %s a pris votre List fichers partage./n",recvChat.message);
  205.             
  206.                 strcpy(returnMsg.type,"MSG");
  207.                 strcpy(returnMsg.message,recvChat.message);
  208.                 strcpy(returnMsg.contenu,myListFichier);
  209.             
  210.                 
  211.                 write(sockfd, &returnMsg, sizeof(returnMsg));
  212.             }
  213.             
  214.             if(strcmp(recvChat.type, "INFO")==0){
  215.                 printf("SERVEUR : contenu %s/n",recvChat.contenu);
  216.             }
  217.             else if(strcmp(recvChat.type, "MSG")==0 || strcmp(recvChat.type, "FILE")==0 ||strcmp(recvChat.type, "FILELINE")==0){
  218.                 if(ignoreList(recvChat.message)==0){
  219.                     
  220.                     if(strcmp(recvChat.type, "FILE")==0){       
  221.                         strcpy(nameFile,"");        
  222.                         strcat(nameFile,recvChat.contenu);
  223.                         strcat(nameFile,recvChat.message);
  224.             
  225.                         printf("nameFile == %s/n",nameFile);
  226.                             
  227.                         if((target=open(nameFile, O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0){
  228.                              perror("IMPOSSIBLE DE CREE UNE FICHE!!/n");
  229.                         }                                                                   
  230.                     }else if(strcmp(recvChat.type, "FILELINE")==0){
  231.                         
  232.                         write(target,recvChat.contenu,strlen(recvChat.contenu));
  233.                     }
  234.                     
  235.                     printf("CLIENT : message %s,contenu %s/n",recvChat.message,recvChat.contenu);
  236.                 }else{
  237.                     printf("IL Y A UNE MESSAGE ETE IGNORE/n");
  238.                 }
  239.             }
  240.         }   
  241. }
  242. //--------------------------------------------------------------------------------------
  243. int main(int argc, char **argv){
  244.     
  245.     int                 sockfd;
  246.     struct sockaddr_in  servaddr;
  247.     //-----------------------udp----------------------------------
  248.     if((server_host_name = gethostbyname(host_name)) == 0){
  249.     perror("gethostbyname");
  250.     exit(EXIT_FAILURE);
  251.     }   
  252.  /*bzero(&sin, sizeof(sin));*/
  253. memset(&sin, 0, sizeof(sin));
  254.   sin.sin_family = AF_INET;
  255.   sin.sin_addr.s_addr = htonl(INADDR_ANY);
  256.   sin.sin_port = htons(port);
  257.   if((socket_descriptor = socket(PF_INET, SOCK_DGRAM, 0)) == -1) { 
  258.     perror("socket");
  259.     exit(EXIT_FAILURE);
  260.  }
  261.  /* 调用bind之前,设置套接口选项启用多播IP支持*/
  262.  loop = 1;
  263.  if(setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &loop, sizeof(loop)) < 0){
  264.      
  265.  perror("setsockopt:SO_REUSEADDR");
  266.  exit(EXIT_FAILURE);
  267.  }
  268. if(bind(socket_descriptor, (struct sockaddr *)&sin, sizeof(sin)) < 0){
  269.    perror("bind"); 
  270.    exit(EXIT_FAILURE);
  271.   }
  272. /* 在同一个主机上进行广播设置套接口,作用是方便单个开发系统上测试多播IP广播 */ 
  273. loop = 1; 
  274. if(setsockopt(socket_descriptor, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {   
  275.  perror("setsockopt:IP_MULTICAST_LOOP");
  276.  exit(EXIT_FAILURE); 
  277.    } 
  278.  /* 加入一个广播组。进一步告诉Linux内核,特定的套接口即将接受广播数据*/ 
  279.  //command.imr_multiaddr.s_addr = inet_addr("224.1.1.1"); 
  280.  //command.imr_interface.s_addr = htonl(INADDR_ANY);
  281.   command.imr_multiaddr.s_addr   =   inet_addr(host_name);  
  282.   command.imr_address.s_addr   =   htonl(INADDR_ANY);  
  283.   command.imr_ifindex      =   2;   
  284.  if(command.imr_multiaddr.s_addr == -1) {  
  285.  perror("224.0.0.1 not a legal multicast address"); 
  286.  exit(EXIT_FAILURE); 
  287.     }
  288. if (setsockopt(socket_descriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0){   
  289.   //perror("setsockopt:IP_ADD_MEMBERSHIP");
  290.     } 
  291.     //--------------------------------------------------------------
  292.     if (argc != 2){
  293.         printf("problem of argument/n");
  294.         exit(-1);
  295.     }       
  296.     if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
  297.         printf("problem of socket/n");
  298.         exit(-1);
  299.     }
  300.     bzero(&servaddr, sizeof(servaddr));
  301.     servaddr.sin_family = AF_INET;
  302.     servaddr.sin_port   = htons(49156); 
  303.     if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
  304.         printf("problem of socket/n");
  305.         exit(-1);
  306.     }   
  307.     if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
  308.         err_sys("connect error");   
  309.     
  310.     str_cli(stdin,sockfd);  
  311.         
  312.     exit(0);
  313. }

 

  1. #include        "chathead.h"
  2. time_t                  ticks;
  3. char                    buff[MAXLINE];
  4. int                     id_Mp;  //id du memore pargage
  5. struct chatBind*        p;  
  6. int                     id_of_semid;
  7. int                     id_of_semget;
  8. //------udp-------------------------------
  9. int                     port = 6789;
  10. int                     socket_descriptor;  
  11. struct                  sockaddr_in address; 
  12. char                    returnList[1024]; 
  13. static  FILE *fp2;
  14. int checkItem(int count,struct chatBind* cb){
  15.     int i;
  16.         
  17.     for (i=0; i<=count;i++){
  18.         if(strcmp(cb->nom,(p+i)->nom)==0)
  19.         return 0;
  20.     }
  21.     return 1;
  22. }
  23. int getList(){
  24.     
  25.     int                 ii;
  26.     
  27.     printf("--------------LIST-------------/n");
  28.     for (ii=0; ii<=9;ii++){
  29.         //if(strcmp((p+ii)->nom,"0")==1){       
  30.             printf("NOM [%s], SALON [%s],socket id [%d]/n,",(p+ii)->nom,(p+ii)->salon,(p+ii)->id_socket);           
  31.             strcat(returnList,"NOM:");
  32.             strcat(returnList,(p+ii)->nom);
  33.             strcat(returnList,",");
  34.             strcat(returnList,"SALON:");
  35.             strcat(returnList,(p+ii)->salon);
  36.             strcat(returnList," | ");
  37.         //}
  38.     }   
  39.     strcat(returnList,"/n");    
  40.     printf("--------------LIST-------------/n");    
  41.     return 2;
  42. }
  43. void bordcast(char *string){
  44.         
  45.     //-----------------------udp-------------------------------------
  46.         if(sendto(socket_descriptor, string, 1024, 0, (struct sockaddr *)&address, sizeof(address)) < 0) {  
  47.                  perror("sendto");  
  48.                  exit(EXIT_FAILURE); 
  49.         }   
  50.     //--------------------------------------------------------- 
  51. }
  52. //oui 1,non 0
  53. int bind_nom_and_ip(struct chatMessage* point,int sockfd){
  54.     
  55.     struct chatBind     cb;
  56.     //int               ii;
  57.     struct sembuf       sb;
  58.     struct semid_ds     ds;
  59.     unsigned short      array[100];
  60.     int                 count;
  61.     int                 returnValeur=0;
  62.     unsigned int        len;
  63.     struct sockaddr_in  ss;
  64.     
  65.     getpeername(sockfd,(struct sockaddr*)&ss,&len);
  66.                     
  67.     cb.id_socket=sockfd;
  68.     memcpy(cb.salon,"PUBLIC",sizeof(cb.salon));
  69.     memcpy(cb.nom,point->message,sizeof(cb.nom));
  70.     
  71.     cb.id_socket=sockfd;
  72.     
  73.     ds.sem_nsems = 0;   
  74.     semctl(id_of_semget, 0, IPC_STAT, &ds); 
  75.     semctl(id_of_semget, 0, GETALL,array);  
  76.     count=array[0];
  77.     
  78.     if(checkItem(count,&cb)!=0){
  79.         memcpy(p+count, &cb, sizeof(struct chatBind));
  80.         sb.sem_num = 0; 
  81.         sb.sem_op = 1;  
  82.         sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
  83.         semop(id_of_semget, &sb, 1);
  84.         returnValeur=1;
  85.     }else{
  86.         printf("IP:%s,NOM:%s,SALON:%s,Port:%ld./n",cb.ip,cb.nom,cb.salon,cb.port);
  87.         
  88.     }
  89.     /*printf("...LIST..../n");
  90.     for (ii=0; ii<=count;ii++){
  91.         printf("NOM [%s], IP  [%s], PORT [%d]/n,",(p+ii)->nom,(p+ii)->ip,(p+ii)->port);
  92.     }*/         
  93.     return returnValeur;
  94. }
  95. int getSockbyNom(char* cp){
  96.     
  97.     int     ii;
  98.     char    newOne[1024];
  99.     
  100.     strcat(cp,"/n");
  101.     sscanf(cp,"%[^/n]",newOne);
  102.     
  103.     for(ii=0; ii<=9;ii++){  
  104.         //printf("/n TEST    %s  %s  %d",(p+ii)->nom,cp,strcmp((p+ii)->nom, cp));
  105.         if(strcmp((p+ii)->nom, newOne)==1){
  106.          //printf("id sockfd ///// %d",(p+ii)->id_socket);  
  107.          return (p+ii)->id_socket;
  108.          break;
  109.         }
  110.     }
  111.     
  112.     return -1;
  113. }
  114. void getNometSalonParSocket(char* cp,int socketId){
  115.     
  116.     int                 ii;
  117.     
  118.     for (ii=0; ii<=20;ii++){        
  119.         if((p+ii)->id_socket==socketId){            
  120.             strcat(cp," NOM:");
  121.             strcat(cp,(p+ii)->nom);
  122.             strcat(cp,",");
  123.             strcat(cp,"DANS SALON:");
  124.             strcat(cp,(p+ii)->salon);
  125.             break;
  126.         }
  127.     }       
  128. }
  129. void getNomParSocket(char* cp,int socketId){
  130.     
  131.     int                 ii;
  132.     
  133.     for (ii=0; ii<=20;ii++){        
  134.         if((p+ii)->id_socket==socketId){            
  135.             
  136.             memcpy(cp,"",sizeof(cp));
  137.             //printf("id de socket de la destination est in a fonction %s /n",cp);
  138.             //printf("id de socket de la destination est in a fonction (p+ii)->nom %s /n",(p+ii)->nom);
  139.             
  140.             strcat(cp,(p+ii)->nom);
  141.             
  142.             break;
  143.         }
  144.     }       
  145. }
  146. int sendMsg(struct chatMessage* cm,int sockfd){
  147.     
  148.     int         returnf=getSockbyNom(cm->message);
  149.     struct      chatMessage crm;
  150.     char        a[1024];
  151.     
  152.     printf("cm->message %s",cm->message);
  153.     printf("returnf %d",returnf);
  154.     
  155.     if(returnf==-1){
  156.         return 4; 
  157.     }
  158.     else{
  159.         printf("id de socket de la destination est %d/n",returnf);
  160.         getNomParSocket(a,sockfd);
  161.         
  162.         memcpy(crm.type,"MSG",sizeof(crm.type));
  163.         memcpy(crm.message,a,sizeof(a));
  164.         memcpy(crm.contenu,cm->contenu,sizeof(crm.contenu));
  165.         
  166.         memcpy(a,"",sizeof(a));
  167.         
  168.         write(returnf,&crm,sizeof(crm));
  169.         return 3;
  170.     }
  171.     
  172. }
  173. int getIDofPointbySockId(int sockfd){
  174.     
  175.     int pointId;
  176.     
  177.     for (pointId=0; pointId<=20;pointId++){     
  178.         if((p+pointId)->id_socket==sockfd){                                             
  179.             return pointId;
  180.             break;
  181.         }
  182.     }           
  183.     return -1;
  184. }
  185. /* resussi return 5
  186.  * else return 6 
  187.  */
  188. int changeSalon(struct chatMessage* cm,int sockfd){
  189.     
  190.     if(getIDofPointbySockId(sockfd)==-1){
  191.         return 6;
  192.     }else{
  193.         //change salon
  194.         //printf("get id of table %d/n",getIDofPointbySockId(sockfd));
  195.         memcpy((p+getIDofPointbySockId(sockfd))->salon,cm->message,sizeof((p+getIDofPointbySockId(sockfd))->salon));    
  196.         return 5;
  197.     }   
  198. }
  199. /* resussi return 7
  200.  * else return 8 
  201.  */
  202. int sendMessageSalon(struct chatMessage* cm,int sockfd){
  203.   
  204.   int                   t;
  205.   char                  cp[1024];
  206.   struct chatMessage    crm;
  207.   int                   returnInt=8;
  208.   
  209.   
  210.    //cherche nom de salon et envoyer une message à chaque socke 
  211.   for (t=0; t<=20;t++){
  212.             
  213.         if(strcmp((p+t)->salon,cm->message)==0){
  214.                 
  215.             getNomParSocket(cp,sockfd); 
  216.                     
  217.             memcpy(crm.type,"MSG",sizeof(crm.type));
  218.             memcpy(crm.message,&cp,sizeof(crm.message));
  219.             memcpy(crm.contenu,cm->contenu,sizeof(crm.contenu));            
  220.         
  221.             printf("________%d/n",(p+t)->id_socket);    
  222.             printf("crm.type %s/n",crm.type);
  223.             printf("crm.message %s/n",crm.message);
  224.             printf("crm.contenu %s/n",crm.contenu);
  225.                 
  226.             write((p+t)->id_socket,&crm,sizeof(crm));
  227.             
  228.             memcpy(cp,"",sizeof(cp));
  229.             
  230.             returnInt=7;
  231.         }
  232.     }   
  233.   return returnInt;
  234. }
  235. /* si reussi return 9, sinon return 10 */
  236. int envoyerFile(struct chatMessage* cm,int sockfd){
  237.     
  238.     int                 destinationSocket;
  239.     char                sourceName[1024];   
  240.     struct  chatMessage  crm;   
  241.     
  242.     //envoyer file
  243.     printf("Two done %s /n",cm->type);
  244.     
  245.     destinationSocket=getSockbyNom(cm->message);
  246.     printf("destination Socket est %d/n",destinationSocket);    
  247.     if(strcmp(cm->type, "FILE")==0){
  248.     
  249.     getNomParSocket(sourceName,sockfd);
  250.     
  251.     strcpy(crm.message,sourceName);
  252.     strcpy(crm.type,"FILE");
  253.     strcpy(crm.contenu,cm->contenu);    
  254.     
  255.     write(destinationSocket,&crm,sizeof(crm));
  256.       
  257.       return 9; 
  258.     }else if(strcmp(cm->type, "FILELINE")==0){
  259.         
  260.         printf("Three done %s /n",cm->type);
  261.                 printf("destinationSocket est dans Fileline %d/n",destinationSocket);
  262.         strcpy(crm.message,sourceName);
  263.         strcpy(crm.type,"FILELINE");
  264.         strcpy(crm.contenu,cm->contenu);
  265.         
  266.         
  267.         printf("crm.contenu == %s /n",crm.contenu);
  268.         
  269.         write(destinationSocket,&crm,sizeof(crm));
  270.     
  271.         return 10;
  272.     }   
  273.     return 11;
  274.     
  275. }
  276. void getMyFichePartage(char *pList){
  277.     
  278.     DIR             *pdir;
  279.     struct dirent   *pent;
  280.     
  281.     strcpy(pList,"");
  282.     
  283.     if((pdir=opendir("./partage"))==NULL)
  284.     {
  285.         fprintf(stderr,"open dir failed./n");
  286.     }
  287.     while(1){
  288.         pent=readdir(pdir);
  289.         if(pent==NULL)break;
  290.         strcat(pList,"/n");
  291.         strcat(pList,pent->d_name);     
  292.         //fprintf(stderr,"%5d %s/n",pent->d_ino,pent->d_name);
  293.     }
  294.     closedir(pdir);
  295.     
  296. }
  297. //12 oui, 13 non
  298. int getListFiche(struct chatMessage* cm,int sockfd){
  299.     
  300.     char        serveurList[1024];
  301.     struct      chatMessage  crm;
  302.     int         a;
  303.     char        nomDuSource[1024];
  304.     
  305.     
  306.     if(strcmp(cm->message, "SER")==0){
  307.         
  308.         getMyFichePartage(serveurList);
  309.     
  310.         
  311.         strcpy(crm.message,"");
  312.         strcpy(crm.type,"INFO");
  313.         strcpy(crm.contenu,serveurList);
  314.         
  315.         printf("Des fichiers partages sous le serveur sont:  %s /n",crm.contenu);
  316.         printf("type:  %s /n",crm.type);
  317.         printf("sockfd:  %d/n",sockfd);
  318.         
  319.         write(sockfd,&crm,sizeof(crm));
  320.         
  321.         return 12;
  322.     }
  323.     else{
  324.         
  325.         a=getSockbyNom(cm->message);
  326.         getNomParSocket(nomDuSource,sockfd);
  327.         
  328.         if(a!=-1){  
  329.             
  330.             strcpy(crm.message,nomDuSource);
  331.             strcpy(crm.type,"GETLIST");
  332.             strcpy(crm.contenu,"");
  333.             
  334.             printf("nomDuSource:  %s /n",nomDuSource);
  335.             printf("type:  %s /n",crm.type);
  336.             printf("sockfd:  %d/n",a);
  337.             
  338.             write(a,&crm,sizeof(crm));
  339.         
  340.         return 12;
  341.         }
  342.         
  343.         
  344.     }
  345.     return 13;
  346. }
  347. //14 oui, 15 non
  348. int telecharger(struct chatMessage* cm,int sockfd){
  349.     
  350.     struct      chatMessage  crm;
  351.     int         a;
  352.     char        nomDuSource[1024];
  353.     char        nomDefiche[1024];
  354.     int                 source;
  355.     register int        k;
  356.     char                buf[4000];
  357.     
  358.     if(strcmp(cm->message, "SER")==0){
  359.         
  360.         strcpy(nomDefiche,"./partage/");
  361.         strcat(nomDefiche,cm->contenu);
  362.         
  363.         strcpy(crm.type,"FILE");
  364.         strcpy(crm.message,"_SERVEUR");
  365.         strcpy(crm.contenu,cm->contenu);
  366.         
  367.         printf("nomDefiche %s",nomDefiche);
  368.         printf("sockfd %d",sockfd);
  369.         
  370.         if((source=open(nomDefiche,O_RDONLY))<0){
  371.                 perror("Problem sur le source");
  372.             
  373.             }else{
  374.             
  375.                 lseek(source,O_WRONLY,-1);
  376.                 write(sockfd,&crm,sizeof(crm));
  377.                 
  378.                 while((k=read(source,buf,sizeof(buf)))>0){
  379.                     sleep(1);
  380.                     
  381.                      strcpy(crm.contenu,buf);
  382.                      strcpy(crm.type,"FILELINE");
  383.                                          
  384.                      write(sockfd,&crm,sizeof(crm));
  385.                 }
  386.                 printf("ENVOYER FICHE EST TERMINE/n");
  387.                 close(source);  
  388.             }       
  389.         
  390.         return 14;
  391.     }
  392.     else{
  393.         
  394.         a=getSockbyNom(cm->message);
  395.         getNomParSocket(nomDuSource,sockfd);
  396.         
  397.         if(a!=-1){  
  398.             
  399.             strcpy(crm.message,nomDuSource);
  400.             strcpy(crm.type,"TELEFILE");
  401.             strcpy(crm.contenu,cm->contenu);
  402.             
  403.             printf("nomDuSource:  %s /n",nomDuSource);
  404.             printf("type:  %s /n",crm.type);
  405.             printf("contenu:  %s /n",crm.contenu);
  406.             printf("sockfd:  %d/n",a);
  407.             
  408.             write(a,&crm,sizeof(crm));
  409.             
  410.         return 14;
  411.         
  412.     }
  413.     }
  414.     return 15;
  415. }
  416. int distinger(struct chatMessage* point,int sockfd){
  417.     
  418.     int returnInt=0;
  419.     
  420.     if(point->statu==1){
  421.         
  422.         
  423.         printf(" general type %s/n",point->type);
  424.         printf(" general message %s/n",point->message);
  425.         printf(" general contenu %s/n",point->contenu);
  426.         
  427.         if(strcmp(point->type, "NOUVEAU")==0){
  428.             
  429.             return(bind_nom_and_ip(point,sockfd));
  430.                         
  431.         }else if(strcmp(point->type, "LIST")==0){
  432.         
  433.             return(getList());
  434.             
  435.         }else if(strcmp(point->type, "TELE")==0){
  436.         
  437.             return(telecharger(point,sockfd));
  438.             
  439.         }else if(strcmp(point->type, "MSG")==0){
  440.             //printf("Type %s  Gen %s  Contenu %s/n",point->type,point->message,point->contenu);
  441.             return(sendMsg(point,sockfd));
  442.             
  443.         }else if(strcmp(point->type, "SALON")==0){
  444.             
  445.             return(changeSalon(point,sockfd));
  446.             
  447.         }else if(strcmp(point->type, "MSGS")==0){
  448.             
  449.             return(sendMessageSalon(point,sockfd));
  450.             
  451.         }else if(strcmp(point->type, "FILE")==0 || strcmp(point->type, "FILELINE")==0){
  452.             
  453.             printf("First done %s /n",point->type);
  454.             return(envoyerFile(point,sockfd));  
  455.         
  456.         }else if(strcmp(point->type, "LISTF")==0){
  457.             
  458.             return(getListFiche(point,sockfd)); 
  459.             
  460.         
  461.         }else{
  462.             
  463.             return 100;
  464.         }
  465.         point->statu=2;
  466.     }   
  467.     return returnInt;
  468. }
  469. void getNometSalonParIPetPort(char* cp,struct sockaddr_in* s){
  470.     
  471.     int                 ii;
  472.     
  473.     for (ii=0; ii<=20;ii++){
  474.         if(
  475.             strcmp(inet_ntop(AF_INET,&s->sin_addr,buff,sizeof(buff))
  476.             ,
  477.             (p+ii)->ip)==0
  478.             ){          
  479.         if(ntohs(s->sin_port)==(p+ii)->port)
  480.         {
  481.             //printf("NOM[%s],SALON[%s]/n",(p+ii)->nom,(p+ii)->salon);
  482.             strcat(cp," NOM:");
  483.             strcat(cp,(p+ii)->nom);
  484.             strcat(cp,",");
  485.             strcat(cp,"DANS SALON:");
  486.             strcat(cp,(p+ii)->salon);
  487.             break;
  488.         }
  489.             
  490.         }
  491.     }
  492. }
  493. void deleteInfo(int  socketId){
  494.     
  495.     int                 ii;
  496.     
  497.     for (ii=0; ii<=20;ii++){        
  498.         if((p+ii)->id_socket==socketId){            
  499.             
  500.             strcpy((p+ii)->ip,"");
  501.             strcpy((p+ii)->nom,"");
  502.             strcpy((p+ii)->salon,"");
  503.             (p+ii)->id_socket=0;
  504.             (p+ii)->port=0;
  505.             break;
  506.         }
  507.     }       
  508. }
  509.     
  510. void str_echo(int sockfd){
  511.     
  512.     ssize_t                 n;
  513.     struct chatMessage      cm,returnMessage;   
  514.     unsigned int            len;
  515.     struct sockaddr_in      ss;
  516.     int                     distinge;
  517.     char                    a[100];
  518.     
  519.     getpeername(sockfd,(struct sockaddr*)&ss,&len);             
  520.         
  521.     for ( ; ; ) {
  522.             
  523.         if((n=read(sockfd,&cm,sizeof(cm)))==0) {
  524.             getNomParSocket(a,sockfd);
  525.             strcat(a," EST PARTI ");    
  526.             bordcast(a);  
  527.             printf("%s",a);
  528.             memcpy(a,"",100);
  529.             deleteInfo(sockfd);                 
  530.             return;
  531.         }else{  
  532.             printf("il y a une nouvelle message/n.");           
  533.             distinge=distinger(&cm,sockfd);
  534.             printf("distinge %d/n",distinge);
  535.             
  536.             
  537.             if(distinge==0){
  538.                 memcpy(returnMessage.type,"INFO",1024);
  539.                 memcpy(returnMessage.contenu,"DESOLE,CE NOM EST OCCUPE/n",1024);
  540.             
  541.             }else if(distinge==1){
  542.                 
  543.                 memcpy(returnMessage.type,"INFO",1024);
  544.                 memcpy(returnMessage.contenu,"CE NOM EST ACCEPTE./n",1024);
  545.                 getNometSalonParSocket(a,sockfd);
  546.                 strcat(a," EST ARRIVE ");
  547.                 bordcast(a);
  548.                 memcpy(a,"",100);
  549.                 
  550.             }else if(distinge==2){
  551.                 
  552.                 memcpy(returnMessage.type,"INFO",1024);
  553.                 memcpy(returnMessage.contenu,returnList,1024);
  554.                 
  555.                 memcpy(returnList,"",1024);
  556.                 
  557.             }else if(distinge==3){
  558.                 
  559.                 memcpy(returnMessage.type,"INFO",1024);             
  560.                 memcpy(returnMessage.contenu,"MESSAGE EST ENVOYE/n",1024);
  561.                 memcpy(returnList,"",1024);
  562.                 
  563.             }else if(distinge==4){
  564.                 
  565.                 memcpy(returnMessage.type,"INFO",1024);
  566.                 memcpy(returnMessage.contenu,"MESSAGE ENVOYE ECHOC, CAR IL‘Y A PAS DE NOM CORRESPONDANT/n",1024);
  567.                 
  568.             }else if(distinge==5){
  569.                 
  570.                 memcpy(returnMessage.type,"INFO",1024);
  571.                 memcpy(returnMessage.contenu,"VOUS AVEZ CHANGE LE SALON/n",1024);
  572.             
  573.             }else if(distinge==6){
  574.             
  575.                 memcpy(returnMessage.type,"INFO",1024);
  576.                 memcpy(returnMessage.contenu,"CHANGE LE SALON ECHOC/n",1024);
  577.             
  578.             }else if(distinge==7){
  579.             
  580.                 memcpy(returnMessage.type,"INFO",1024);
  581.                 memcpy(returnMessage.contenu,"MESSAGE EST ENVOYE (SALON) /n",1024);                 
  582.             
  583.             }else if(distinge==8){
  584.             
  585.                 memcpy(returnMessage.type,"INFO",1024);
  586.                 memcpy(returnMessage.contenu,"MESSAGE ENVOYE ECHOC (SALON)/n",1024);        
  587.             
  588.             }else if(distinge==9){
  589.             
  590.                 memcpy(returnMessage.type,"INFO",1024);
  591.                 memcpy(returnMessage.contenu,"FILE ENVOYE COMMENCE (SALON)/n",1024);        
  592.             
  593.             }else if(distinge==10){
  594.             
  595.                 memcpy(returnMessage.type,"INFO",1024);
  596.                 memcpy(returnMessage.contenu,"FILE ENVOYE TERMINE (SALON)/n",1024);
  597.         
  598.             }else if(distinge==11){
  599.             
  600.                 memcpy(returnMessage.type,"INFO",1024);
  601.                 memcpy(returnMessage.contenu,"FILE ENVOYE ECHOC (SALON)/n",1024);
  602.             
  603.             }else if(distinge==12){
  604.             
  605.                 memcpy(returnMessage.type,"INFO",1024);
  606.                 memcpy(returnMessage.contenu,"PRENDRE LIST REUSSIR./n",1024);       
  607.             
  608.             }else if(distinge==13){
  609.             
  610.                 memcpy(returnMessage.type,"INFO",1024);
  611.                 memcpy(returnMessage.contenu,"PRENDRE LIST DE LA FICHIER ECHOC./n",1024);
  612.             
  613.             }else if(distinge==14){
  614.             
  615.                 memcpy(returnMessage.type,"INFO",1024);
  616.                 memcpy(returnMessage.contenu,"TELECHARGER COMMENCER./n",1024);  
  617.                 
  618.             }else if(distinge==15){
  619.             
  620.                 memcpy(returnMessage.type,"INFO",1024);
  621.                 memcpy(returnMessage.contenu,"TELECHARGER ECHOC./n",1024);                  
  622.             
  623.             
  624.             }else if(distinge==100){
  625.             
  626.                 memcpy(returnMessage.type,"INFO",1024);
  627.                 memcpy(returnMessage.contenu,"COMMANDE INCONNU/n",1024);
  628.                 
  629.             }
  630.             /*else{
  631.                 memcpy(returnMessage.type,"INFO",1024);
  632.                 //memcpy(returnMessage.contenu,"SERVER:CE NOM EST NOT ACCEPTE./n",1024);
  633.                 memcpy(returnMessage.contenu,"CE NOM EST NOT ACCEPTE./n",1024);
  634.             }*/
  635.             
  636.                 write(sockfd,&returnMessage,sizeof(returnMessage));
  637.             }   
  638.         }
  639. }
  640. static void* doit(void *arg){
  641.     
  642.     int connfd;
  643.     
  644.     
  645.     connfd=*((int *)arg);
  646.     pthread_detach(pthread_self());
  647.     str_echo(connfd);
  648.     close(connfd);
  649.     return(NULL);
  650. }
  651. void *envoyerMessageParServer(void) {
  652.     char                sendline[10];
  653.     
  654.     struct chatMessage  cm;
  655.     
  656.     //while(fgets(sendline,10,fp2)!=NULL)
  657.     while(scanf("%s",sendline)){
  658.     
  659.     if(strlen(sendline)>0)
  660.     {
  661.         sscanf(sendline,"%10[^:]:%200[^:]:%200[^/n]",cm.type,cm.message,cm.contenu); 
  662.         strcpy(sendline,"");
  663.         
  664.         if(strcmp(cm.type,"INFO")==0){
  665.             printf("%s/n",cm.message);
  666.             bordcast(cm.message);
  667.             printf("VOUS AVEZ BRODCAST UNE MESSAGE./n");
  668.         }
  669.     }
  670.     }
  671.     
  672. }
  673. int main(int argc, char **argv)
  674. {
  675.     int                     listenfd,*iptr;
  676.     struct sockaddr_in      servaddr;
  677.     socklen_t               clilen;
  678.     pthread_t               tid;
  679.     struct sockaddr_in      cliaddr;    
  680.     pthread_t               serveur;
  681.      
  682.     // udp---------------------------------------------------------------------
  683.    socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);  
  684.     if (socket_descriptor == -1) {      
  685.       perror("Opening socket"); 
  686.        exit(EXIT_FAILURE);  
  687.       }   
  688.     int   opt   =   1;  
  689.         int   len   =   sizeof(opt);  
  690.     setsockopt(socket_descriptor,   SOL_SOCKET,   SO_BROADCAST,   (char   *)&opt,   len);  
  691.       
  692.     memset(&address, 0, sizeof(address));   
  693.     address.sin_family = AF_INET;  
  694.     address.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  695.     address.sin_port = htons(port);  
  696.     
  697.     //------------------------------------------------------------------------
  698.     id_Mp = shmget(0x213, sizeof(struct chatBind)*30, 0666|IPC_CREAT|IPC_EXCL);
  699.     p= (struct chatBind* )shmat(id_Mp, 0, 0);
  700.     
  701.     id_of_semid=2014;
  702.     id_of_semget=semget(id_of_semid, 2, 0666|IPC_CREAT|IPC_EXCL);
  703.     semctl(id_of_semget, 0, SETVAL, 0);// counter pour le memoire partage
  704.     
  705.     listenfd =socket(AF_INET, SOCK_STREAM, 0);
  706.     bzero(&servaddr, sizeof(servaddr));
  707.     servaddr.sin_family      = AF_INET;
  708.     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  709.     servaddr.sin_port        = htons(49156);    
  710.     bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
  711.     listen(listenfd, 1024);     
  712.     
  713.     pthread_create(&serveur,NULL,&envoyerMessageParServer,NULL);    
  714.     
  715.     for ( ; ; ) {           
  716.             
  717.         clilen = sizeof(cliaddr);
  718.         iptr=malloc(sizeof(int));
  719.         *iptr = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
  720.         printf("IL Y A NOUVEAU CLIENT EST ARRIVE IP [ %s], PORT [ %d]./n",
  721.                 inet_ntop(AF_INET,&cliaddr.sin_addr,buff,sizeof(buff)),
  722.                 ntohs(cliaddr.sin_port)
  723.                 );
  724.         printf("son id de socket est %d/n",*iptr);              
  725.         pthread_create(&tid,NULL,&doit,iptr);   
  726.     }
  727.     
  728.         
  729.     exit(EXIT_SUCCESS); 
  730. }

 

都在这里了,现在贴一个使用说明哦

 

 

 

 

Rapport du Réseau

 

Projet Réseau et Communication

 


 

 

 

Table des matières

 

Introduction et Remerciements ....................................... page 1

Analyser du cas ................................................................... page 2

Manuel d‘utilisation ......................................................... page 2-5

 

 

 

Introduction et Remerciements

Le but de ce projet est pour réaliser un logiciel ? chat ? sou la systeme de Linux par la langage ? ? et  ? c++ ? pour mieux comprendre des protocoles connus de l‘internent et vise à mettre en oeuvre des communication entre processus.

Le r?le du serveur qui est s‘occupe transmettre des message entre des clients et aussi offre des fonctions pour des clients.

Le r?le de client peut rejoindre la discussion et parler avec les autre par le serveur, il peut parler avec un seul client et aussi parler avec tous dans le salon. Mais d‘abord ils faut envoyer leur identifiant par noter que le serveur, il y a nouveau client est arrivé. Le serveur va vérifier si ce nom est unique ou pas. Une fois que le client est correctement identifié, il peut alors commencer à envoyer des messages et recevoir des message par ? Chat ?.

Par ce projet, on a mieux compris les différence entre des protocoles, et compris comment travaille avec ? processus ? sous linux.

C‘est vraiment de la chance pour nous faire la pratique. Et nous remercions sincèrement de notre professeurs pour votre aider.

Analyser du cas

1,Udp ,Tcp ou avec deux?

D‘aborde, le plus importants est choir un protocole pour réaliser le ? chat ?. TCP ou UDP, on considère le  priorité de TCP est  un protocole de transport fiable et on peut le utilise pour envoyer des messages et recevoir des message entre le serveur et des clients,car Le c?té client de la connexion effectue une ouvertureactive en 3 temps (poignée de mains en trois temps).

Mais, les broadcast ont lieu au niveau des adresses destination : mac et IP pas au niveau des protocoles . l‘adressage dans ces protocoles se fait par les ports, il n‘y a pas de port broadcast comme il y a une adresse broadcast . par contre, UDP peut être transporté dans des paquets broadcast car il fonctionne en mode non connecté tandis que TCP ne peut pas être transporté dans des paquets broadcast car il fonctionne en mode connecté .

On utilise le protocole UDP pour réaliser la fonction de ? broadcast ?, par exemple le serveur peut envoyer des message à tout les clients comme des fonctions PARTANTS et utilise le protocole TCP pour prendre les commandes comme LIST, NOUVEAU, MESSAGE etc.

2,Structure de Message

Le but de ce outil est envoyer des messages et recevoir des messages entre des client, on définit la structure de message ci-dessous:

struct chatMessage {

int statu; //définit le statue de message, lire pas encore lire etc.

char type[20]; //définit le type de message,

char message[1024]; //définit des information de ce message

char contenu[1024]; //contenu de ce message,

};

Tableau 1 chathead.h

Grace à ce structure, on peut très facile de distinguer et traiter des différents messages.

3,Threads et Verrous

A c?te de serveur, on utiles ? thread ? pour connecter avec chaque client, lorsqu‘il y a un client arrive, le serveur traite le connections avec crée un nouveau ? thread ?, et chaque processus offrent un mécanisme permettant à un processus de réaliser plusieurs unités d‘exécution de fa?on asynchrone.

Et on utiles la fonction ? verrous et variables conditionnelles  car les verrous permettent de partager facilement des données communes accessibles en lecture et écriture. Par exemple le serveur qui stocke les base de donnée pour permet des clients communiquer avec serveur par différence ID de?socket ?,beaucoup de tache travaillent sur un même serveur.

4,La tableau de stockage

on utilise une structure pour attacher un ? Id de socket ?à un vrai nom de utilisateur,lorsqu‘un client arrive, le serveur enregistre ce nom avec son ? socket ?, et puis lorsqu‘il part, on le supprime avec une fonction qui peut tester la statue de ce utilisateur, et tous les information sont stocké par une mémoire partagé. La structure de message ci-dessous:

struct chatBind

{
char ip[50];
// définit IP de chaque client

char nom[20]; // définit nom de ce client correspondant

char salon[20]; // définit ce client dans lequel salon
long int port;
// définit le port de ce utilisateur
int id_socket;
// définit le ID de socket de ce connections
};

Tableau 2 chathead.h

 

Manuel d‘utilisation

D‘abord, on démarre le serveur,qui attende des clients arrivent, l‘address de serveur est local,c‘est-à-dire il est ? 127.0.0.1 ?:

wei@wei-laptop:~/workspace/chat$ ./serveur

 

 

Et puis on démarre deux clients,et l‘argument de client est l‘address de serveur:

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

 

En même temps on peut vois à c?te de serveur qui déserte qu‘il a deux clients arrivent, et imprimer deux phases sur l‘écran,comme au ci-dessous:

wei@wei-laptop:~/workspace/chat$ ./serveur

IL Y A NOUVEAU CLIENT EST ARRIVE IP [ 127.0.0.1], PORT [ 45122].

son id de socket est 5

IL Y A NOUVEAU CLIENT EST ARRIVE IP [ 127.0.0.1], PORT [ 45123].

son id de socket est 6

 

En suite on enregistre le nom de client par le fonction ? NOUVEAU ? à c?te de client, ici on enregistre deux client, il s‘appelle AAA, et l‘autre s‘appelle BBB.

Si ce nom est unique, il peut recevoir une message par serveur ? SERVEUR : type INFO ,contenu CE NOM EST ACCEPTE.  ?,si non, il peut recevoir une message comme ? SERVEUR : CE NOM EST OCCUPE ?.

Lorsque le nom est accepté, le serveur utiliser la communication de type BROADCAST à tout le monde.  ?  SERVEUR: NOM:AAA ,DANS SALON:public EST ARRIVE  ? .Au début tout les clients sont dans le salon ? public ?.

wei@wei-laptop:~/workspace/chat$ ./ client 127.0.0.1

NOUVEAU:AAA

SERVEUR : type INFO ,contenu CE NOM EST ACCEPTE.

SERVEUR: NOM:AAA ,DANS SALON:public EST ARRIVE .

SERVEUR: NOM:BBB ,DANS SALON:public EST ARRIVE .

LIST ,liste les noms de tous les participants à la discussion:

wei@wei-laptop:~/workspace/chat$ ./ client 127.0.0.1

LIST:

SERVEUR :

NOM:AAA ,SALON:public |

NOM:BBB ,SALON:public |

 

MESSAGE(MSG) permet d‘envoyer des messages par un client pour d‘autre client, ici client AAA envoie une message au client BBB;

wei@wei-laptop:~/workspace/chat$ ./ client 127.0.0.1

MSG:BBB:Bonjour

 

Et client BBB qui re?oit une message au ci-dessous:

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

Tu a re?u une message de AAA, contenu est: Bonjour

 

? IGNORE ? fonction permet de client ne recevoir pas des message de quelqu‘un,par exemple, AAA veut ignorer des message de BBB,il est possible de faire comme au ci-dessous:

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

IGNORE:BBB

IGNORE OK

 

Lorsque BBB envoie une message à AAA,AAA peut revoie une message comme au ci-dessous:

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

IGNORE:BBB

IGNORE OK

IL Y A UNE MESSAGE ETE IGNORE

La commande ? UNIGNORE ? peut enlever le fonction ? IGNORE ?

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

UNIGNORE:BBB

UNIGNORE OK

 

Pour changer un salon, il est possible de utiliser le commande ? SALON: nom de salon ?, s‘il a réussi, le serveur réponde une message ?TU A CHANGE LE SALON. ? :

 

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

SALON:MUSIC:

TU A CHANGE LE SALON.

Et c‘est aussi possible de envoyer à tous dans le même salon par un client, il faut utiliser le commande,  ? MSGS:nom de salon:votre parole ?, et tous dans ce salon peut le recevoir.

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

MSGS:MUSIC: tu aime la music ou pas...

 

Pour envoyer une fiche,c‘est possible de faire avec le commande ? FILE: nom : répertoire de fiche ?, comme au ci-dessous:

 

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

FILE:AAA:./test.c

 

Si quelque client part, tout le monde peut recevoir une message ? Le utilisater AAA est parti ?, si le serveur part, tout les utilisateur peut prendre une message aussi, comme ? SERVEUR SHUTOWN ?.

Et en plus, le serveur peut utiliser une commande pour envoyer une message à tous, au ci-dessous:

 

wei@wei-laptop:~/workspace/chat$ ./serveur

INFO: Le serveur va démarrer dans 30 min.

Pour lister des fichier des fichiers présents sur le serveur, il permet de utiliser la commande ? LISTF:SER: ?, et ? TELE:SER:nom de fichier ?pour la récupérer.

 

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

LISTF:SER:

contenu présent sur le serveur

hello.txt

for.in

god.c

TELE:SER:hello.txt

envoyer terminer.

Pour lister des fichier des fichiers présents sur un autre client, il permet de utiliser la commande ? LISTF:nom de client: ?, et ? TELE:nom de client :nom de fichier ?pour la récupérer.

 

wei@wei-laptop:~/workspace/chat$ ./client 127.0.0.1

LISTF:BBB:

contenu présent sur le BBB

a.txt

b.txt

c.txt

TELE:BBB:a.txt

envoyer terminer.

Linux 下 c 语言 聊天软件