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

📄 c.c

📁 linux 下的聊天室程序, 用linux c写一个局域网的聊天室程序,基于组播来实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#i nclude <stdio.h>
#i nclude <stdlib.h>
#i nclude <errno.h>
#i nclude <string.h>
#i nclude <netdb.h>
#i nclude <sys/types.h>
#i nclude <netinet/in.h>
#i nclude <sys/socket.h>
#i nclude <sys/ipc.h>
#i nclude <sys/shm.h>
#i nclude <signal.h>
#define WAITBUF 10
#define PORT 1984
#define CLIENTPORT 2006
#define RECVIPPORT 2008
#define CLIENTNUMBER 10
//#define SHM_KEY 48
struct client{
    char name[13];
    char ip[16];
    int count;
    int state;
};
struct clientmsg{
    char name[12];
    char ip[16];
    int state;
};

void AddToClient(struct client *clients,int numbers,struct clientmsg clientmsg);
void PrintClient(struct client *clients,int numbers);
void DeleteToClient(struct client *clients,int numbers,struct clientmsg clientmsg);
void sigfunc(int signo);
static struct client *clients;
static int seg_id; 
int main(int argc, char *argv[])
{
    int sockfd,new_fd;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    struct sockaddr_in recv_addr;
    int addr_len;
    int recv_len;
    int count=0;
    int i;
    int sin_size;
    struct clientmsg clientmsg;
    pid_t clientmsgpid;
    pid_t recvippid;
    int sockfdip;
    char *mem_ptr;
    int key;
    char sendcount[10];
    struct sigaction act; 
    key=atoi(argv[1]);
    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;
    }
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        fprintf(stderr,"Socket error:%s\n",strerror(errno));
        exit(1);
    }
    bzero(&server_addr,sizeof(struct sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    server_addr.sin_port=htons(PORT);
 if((recvippid=fork()) < 0)
 {
  fprintf(stderr,"fork error:%s\n",strerror(errno));
  exit(1);
 }
 if(recvippid == 0)
 {//recvip
  close(sockfd);
     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);
    DeleteToClient(clients,CLIENTNUMBER,clientmsg);
    printf("leave name:%s\n",clientmsg.name);
  }//while(1)
  
 }//recvip end
    if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
    {
        fprintf(stderr,"Bind error:%s\n",strerror(errno));
        exit(1);
    }
    if(listen(sockfd, WAITBUF)==-1)
    {
        fprintf(stderr,"Listen error:%s\n",strerror(errno));
        exit(1);
    }
 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)
    {
  
     sin_size=sizeof(struct sockaddr_in);
        if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
        {
            fprintf(stderr,"Accept error:%s\n",strerror(errno));
            exit(1);
        }
        if((clientmsgpid=fork()) < 0)
        {
            fprintf(stderr,"clientmsgpid fork error:%s\n",strerror(errno));
            exit(1);
        }
        if(clientmsgpid == 0)
        {
  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);
  }
  if(recv(new_fd,&clientmsg,sizeof(struct clientmsg),0) != sizeof(struct clientmsg))
  {
   fprintf(stderr,"recv error:%s\n",strerror(errno));
   exit(1);
  }
  
  if(clientmsg.state == 1)
  {
   
   if(send(new_fd,clients,sizeof(struct client)*CLIENTNUMBER,0) != sizeof(struct client))
   close(new_fd);
   count++;
   AddToClient(clients,CLIENTNUMBER,clientmsg);
   PrintClient(clients,CLIENTNUMBER);
   printf("\n");
  }
  exit(1);
  
        }//if(clientmsgpid == =0)
 
    }//while(1)
}
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\n",clients[i].name);
   printf("ip:%s\n",clients[i].ip);
  }
 }
}
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 ;
   }
  }
 }
}
void sigfunc(int signo)
{
 int i;
 int sockfd;
     struct sockaddr_in send_addr;
    if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
   {
         fprintf(stderr,"Socket error:%s\n",strerror(errno));
      exit(1);
     }
 for(i=0; i<CLIENTNUMBER; 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(CLIENTPORT);
   if(sendto(sockfd,"***service leave***",19,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);
}

 
client程序
/*    SeaRobberStudio    */
/*BUG and NOTE:
Not join protect to Shared Memory Segments,example Semaphore Arrays.
Not check the parameters validity.
When transmit may be error.
If the client program no right exit,others cannot know,the service program shouldbe check the client program whether exist timing.
The program when exit(), it do not delete the Shared Memory Segments,you maybe use atexit() but the program have some processes.
When one process is exit(),others is continue.
The service program's action is few. 
And so on. */
/*   !print:  print clients message.
 !all:message broadcast message. */
/* programname  serviceip  yourname  key */
#i nclude <stdlib.h>
#i nclude <stdio.h>
#i nclude <errno.h>
#i nclude <string.h>
#i nclude <netdb.h>
#i nclude <sys/types.h>
#i nclude <netinet/in.h>
#i nclude <sys/socket.h>
#i nclude <sys/ipc.h>
#i nclude <sys/shm.h>
#i nclude <arpa/inet.h>
#i nclude <signal.h>
#define WAITBUF 10
#define PORT 1984
#define CLIENTNUMBER 10
#define SHM_KEY 84
#define CLIENTPORT 2006
#define RECVIPPORT 2008 

struct client{
    char name[13];
    char ip[16];
    int count;
    int state;
};
struct clientmsg{
    char name[12];
    char ip[16];
    int state;
};

void AddToClient(struct client *clients,int numbers,struct clientmsg clientmsg);
void PrintClient(struct client *clients,int numbers);
int NameToIp(struct client *clients,int numbers,char *name,char *ip);
void SendToEveryone(struct client *clients,int numbers,int sockfd,int port,struct clientmsg clientmsg);
void DeleteToClient(struct client *clients,int numbers,struct clientmsg clientmsg);
int IpToName(struct client *clients,int numbers,char *name,char *ip);
void SendMsgToEveryone(struct client *clients,int numbers,int sockfd,int port,char *msg);
void sigfunc(int signo);

static struct client *clients;
static struct clientmsg clientmsg;
static char serviceip[16];
static int seg_id; 
int main(int argc, char *argv[])
{
    int sockfd,new_fd,sockfdip;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    struct sockaddr_in send_addr,recv_addr;
    int recv_len;
    int addr_len;
    int count=0;
    int i;
    int sin_size;
    pid_t recvpid;
    pid_t recvippid;
    char *mem_ptr;
    char hostname[30];
    struct hostent *hp;
    int key;
    char msg_buf[BUFSIZ];
    char sendname[13];
    char sendip[16];
    char recvname[13];
    char recvip[16];
    char *sendmsg;
    struct sigaction act; 
    
    if(argc != 4)
    {
     printf("parameter must like: command ip name key\n");
 exit(1);
    }
    if(argv[3][0] == '!')

⌨️ 快捷键说明

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