⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c.c

📁 linux 下的聊天室程序, 用linux c写一个局域网的聊天室程序,基于组播来实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
     printf("the first letter of name isnot '!'\n");
 exit(1);
    }
    if(strlen(argv[3]) > 10)
    {
     printf("the length of name is not more then 10 ");
 exit(1);
    }
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        fprintf(stderr,"Socket error:%s\n",strerror(errno));
        exit(1);
    }
    strncpy(serviceip,argv[1],16);
// printf("service :%s",serviceip);
    bzero(&server_addr,sizeof(struct sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=inet_addr(argv[1]);
    server_addr.sin_port=htons(PORT);
    if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) == -1)
    {
     fprintf(stderr,"Connect error:%s\n",strerror(errno));
 exit(1);
    } 
    key=atoi(argv[3]);
    seg_id=shmget(key,sizeof(struct client)*CLIENTNUMBER,IPC_CREAT | 0600);
    if(seg_id == -1)
    {
     perror("shmget");
 exit(1);
    }
    clients=(struct client *)shmat(seg_id,NULL,0);
    for(i=0; i<CLIENTNUMBER; i++)
    {
        clients[i].state=0;
 clients[i].count=0;
    }
     gethostname(hostname,30);
 hp=gethostbyname(hostname);
 inet_ntop(AF_INET,hp->h_addr,clientmsg.ip,16);
     strncpy(clientmsg.name,argv[2],11);
 clientmsg.state=1;
 if(send(sockfd,&clientmsg,sizeof(struct clientmsg),0) != sizeof(struct clientmsg))
 {
  fprintf(stderr,"send error:%s\n",strerror(errno));
  exit(1);
 }
 if(recv(sockfd,clients,sizeof(struct client)*CLIENTNUMBER,0) == -1)
 {
  fprintf(stderr,"recv error:%s\n",strerror(errno));
  exit(1);
 }
 close(sockfd);
 PrintClient(clients,CLIENTNUMBER);

    if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
   {
         fprintf(stderr,"Socket error:%s\n",strerror(errno));
      exit(1);
     }
 if((recvpid=fork()) < 0)
 {
  fprintf(stderr,"fork error:%s\n",strerror(errno));
  exit(1);
 }
 if(recvpid == 0)
 {//recv
  bzero(&recv_addr,sizeof(struct sockaddr_in));
  recv_addr.sin_family=AF_INET;
  recv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  recv_addr.sin_port=htons(CLIENTPORT);
  if(bind(sockfd,(struct sockaddr*)(&recv_addr),sizeof(recv_addr)) == -1)
  {
   fprintf(stderr,"Bind error:%s\n",strerror(errno));
   exit(1);
  }
  addr_len=sizeof(recv_addr);
  
  while(1)
  {
   recv_len=recvfrom(sockfd,msg_buf,BUFSIZ,0,(struct sockaddr *)&recv_addr,&addr_len);
   msg_buf[recv_len]='\0';
   strncpy(recvip,inet_ntoa(recv_addr.sin_addr),16);
   IpToName(clients,CLIENTNUMBER,recvname,recvip);
   printf("%s say:%s\n",recvname,msg_buf);
  
  }//while(1)
 }//recv end
 if((recvippid=fork()) < 0)
 {
  fprintf(stderr,"fork error:%s\n",strerror(errno));
  exit(1);
 }
 if(recvippid == 0)
 {//recvip
     if((sockfdip=socket(AF_INET,SOCK_DGRAM,0))==-1)
    {
          fprintf(stderr,"Socket error:%s\n",strerror(errno));
       exit(1);
      }
  bzero(&recv_addr,sizeof(struct sockaddr_in));
  recv_addr.sin_family=AF_INET;
  recv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  recv_addr.sin_port=htons(RECVIPPORT);
  if(bind(sockfdip,(struct sockaddr*)(&recv_addr),sizeof(recv_addr)) == -1)
  {
   fprintf(stderr,"RecvIp Bind error:%s\n",strerror(errno));
   exit(1);
  }
  addr_len=sizeof(recv_addr);
  
  while(1)
  {
   recv_len=recvfrom(sockfdip,&clientmsg,sizeof(clientmsg),0,(struct sockaddr *)&recv_addr,&addr_len);
   if(clientmsg.state == 1)
   {
    AddToClient(clients,CLIENTNUMBER,clientmsg);
    printf("join name:%s\n",clientmsg.name);
   }
   else
   {
    DeleteToClient(clients,CLIENTNUMBER,clientmsg);
    printf("leave name:%s\n",clientmsg.name);
   }
  }//while(1)
  
 }//recvip end
 else
 {//send  //father fork
  SendToEveryone(clients,CLIENTNUMBER,sockfd,RECVIPPORT,clientmsg);
  act.sa_handler=sigfunc;
  sigemptyset(&act.sa_mask);
  sigaddset(&act.sa_mask,SIGINT);
  sigaddset(&act.sa_mask,SIGQUIT);
  act.sa_flags=0;
  if(sigaction(SIGINT,&act,NULL) < 0)
  {
   fprintf(stderr,"SIGINT error:%s",strerror(errno));
  }
  if(sigaction(SIGINT,&act,NULL) < 0)
  {
   fprintf(stderr,"SIGINT error:%s",strerror(errno));
  }
  
  while(1)
  {
   memset(msg_buf,0,sizeof(msg_buf));
   fgets(msg_buf,BUFSIZ,stdin);
   if((sendmsg=memchr(msg_buf,':',13)) == NULL)
   {
    printf("no name\n");
    continue;
   }
//   printf("|%s|\n",sendmsg);
   strncpy(sendname,msg_buf,sendmsg-msg_buf);
   sendname[sendmsg-msg_buf]='\0';
   if(strcmp(sendname,"!print") == 0)
   {
    PrintClient(clients,CLIENTNUMBER);
    continue;
   }
   sendmsg++;
   if(sendmsg == NULL)
   {
    printf("no message\n");
    continue;
   }
//   printf("name:%s,ip:%s,msg,%s!\n",sendname,sendip,sendmsg);
   if(strcmp(sendname,"!all") == 0)
   {
    SendMsgToEveryone(clients,CLIENTNUMBER,sockfd,CLIENTPORT,sendmsg);
    continue;
   }
   if(NameToIp(clients,CLIENTNUMBER,sendname,sendip) == -1)
   {
    printf("have no the name\n");
    continue;
   }
   bzero(&send_addr,sizeof(struct sockaddr_in));
       send_addr.sin_addr.s_addr=inet_addr(sendip);
       send_addr.sin_family=AF_INET;
     send_addr.sin_port=htons(CLIENTPORT);
   if(sendto(sockfd,sendmsg,strlen(sendmsg),0,(struct sockaddr *)&send_addr,sizeof(send_addr)) == -1)
   {
    fprintf(stderr,"send error:%s\n",strerror(errno));
   }
  }//while(1)
 }//send end
 
}
void sigfunc(int signo)
{
 int i;
 int sockfd;
     struct sockaddr_in send_addr;
 clientmsg.state=0;
    if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
   {
         fprintf(stderr,"Socket error:%s\n",strerror(errno));
      exit(1);
     }
 SendToEveryone(clients,CLIENTNUMBER,sockfd,RECVIPPORT,clientmsg);
 bzero(&send_addr,sizeof(struct sockaddr_in));
     send_addr.sin_addr.s_addr=inet_addr(serviceip);
     send_addr.sin_family=AF_INET;
   send_addr.sin_port=htons(RECVIPPORT);
 if(sendto(sockfd,&clientmsg,sizeof(clientmsg),0,(struct sockaddr *)&send_addr,sizeof(send_addr)) == -1)
 {
  fprintf(stderr,"send error:%s\n",strerror(errno));
 }
 close(sockfd);
 if(shmctl(seg_id,IPC_RMID,NULL) == -1)
 {
  printf("unlink msg queue error\n");
 }
 if(signal(SIGINT,SIG_DFL) == SIG_ERR)
 {
  fprintf(stderr,"SIGINT SIG_DFL error:%s\n",strerror(errno));
  exit(1);
 }
 if(signal(SIGQUIT,SIG_DFL) == SIG_ERR)
 {
  fprintf(stderr,"SIGQUIT SIG_DFL error:%s\n",strerror(errno));
  exit(1);
 }
 kill(getpid(),signo);
}
void AddToClient(struct client *clients,int numbers,struct clientmsg clientmsg)
{
 int i,len,ch;
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 1)
  {
   if(strcmp(clients[i].name,clientmsg.name) == 0)
   {
    
    clients[i].count++;
    len=strlen(clients[i].name);
    if(clients[i].count < 10)
    {
     (clients[i].name)[len]=clients[i].count+48;
     (clients[i].name)[len+1]='\0';
    }
    if(clients[i].count > 9)
    {
     (clients[i].name)[len]=clients[i].count/10+48;
     (clients[i].name)[len+1]=clients[i].count%10+48;
     (clients[i].name)[len+2]='\0';
     
    }
    AddToClient(clients,numbers,clientmsg);
    clients[i].count=0;
    return ;
   }
  }
 }
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 0)
  {
   clients[i].state=1;
   strncpy(clients[i].name,clientmsg.name,13);
   strncpy(clients[i].ip,clientmsg.ip,16);
   clients[i].count=0;
   break;
  }
 }
}
void PrintClient(struct client *clients,int numbers)
{
 int i;
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 1)
  {
   printf("name:%s ip:%s\n",clients[i].name,clients[i].ip);
  }
 }
}
int NameToIp(struct client *clients,int numbers,char *name,char *ip)
{
 int i;
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 1)
  {
   if(strcmp(clients[i].name,name) == 0)
   {
    strncpy(ip,clients[i].ip,16);
    return 0;
   }
  }
 }
 return -1;
}
int IpToName(struct client *clients,int numbers,char *name,char *ip)
{
 static unnamenumber=0;
 int i;
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 1)
  {
   if(strcmp(clients[i].ip,ip) == 0)
   {
    strncpy(name,clients[i].name,13);
    return 0;
   }
  }
 }
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 0)
  {
   strncpy(clients[i].ip,ip,16);
   sprintf(clients[i].name,"unname%d",unnamenumber);
   clients[i].state=1;
   unnamenumber++;
   strncpy(name,clients[i].name,13);
   return 0;
  }
 }
}
void SendToEveryone(struct client *clients,int numbers,int sockfd,int port,struct clientmsg clientmsg)
{
 int i;
     struct sockaddr_in send_addr;
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 1)
  {
   bzero(&send_addr,sizeof(struct sockaddr_in));
       send_addr.sin_addr.s_addr=inet_addr(clients[i].ip);
       send_addr.sin_family=AF_INET;
     send_addr.sin_port=htons(port);
   if(sendto(sockfd,&clientmsg,sizeof(clientmsg),0,(struct sockaddr *)&send_addr,sizeof(send_addr)) == -1)
   {
    fprintf(stderr,"send error:%s\n",strerror(errno));
   }
  }
 }
}
void SendMsgToEveryone(struct client *clients,int numbers,int sockfd,int port,char *msg)
{
 int i;
     struct sockaddr_in send_addr;
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 1)
  {
   bzero(&send_addr,sizeof(struct sockaddr_in));
       send_addr.sin_addr.s_addr=inet_addr(clients[i].ip);
       send_addr.sin_family=AF_INET;
     send_addr.sin_port=htons(port);
   if(sendto(sockfd,msg,sizeof(msg),0,(struct sockaddr *)&send_addr,sizeof(send_addr)) == -1)
   {
    fprintf(stderr,"send error:%s\n",strerror(errno));
   }
  }
 }
}
void DeleteToClient(struct client *clients,int numbers,struct clientmsg clientmsg)
{
 int i;
 for(i=0; i<numbers; i++)
 {
  if(clients[i].state == 1)
  {
   if(strcmp(clients[i].ip,clientmsg.ip) == 0)
   {
    clients[i].state=0;
    return ;
   }
  }
 }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -