C-TCP中客户端之间的ChatRoom服务

时间:2015-07-16 03:55:59

标签: c linux fork chat ipc

开始使用,我尝试做的是多客户端聊天服务。 我已经阅读了数千个与之相关的帖子,但大多数都是用线程实现的,没有什么可以帮助我,我需要使用FORKS。

我的服务器支持多个客户端的连接。每次客户端请求连接时,服务器都会执行以下操作:

  1. 设置所需的共享变量。
  2. 获取正确的套接字来处理连接,
  3. 当客户端连接时,将客户端的数据保存在用结构实现的客户端数组中
  4. 分叉处理此连接的进程,
  5. 返回并在accept()函数中阻塞另一个客户端。
  6. fork执行以下操作:

    1. 等待用户发送的命令,
    2. 完成请求,
    3. 等待另一个命令。 fork使用受信号量保护的共享客户端阵列。这是通过shm_open,mmap和shm_open在父进程中完成的,以便在子进程之间共享数组。
    4. 目前,只有3个选项是:

      1. clientlist:查看已连接客户端列表
      2. sendchat:向所需客户发送消息,
      3. quit_:退出程序并断开与服务器的连接。
      4. 说出来的问题是,我无法以任何方式注意到客户已经为他准备好了消息。执行流程是:

        1. 客户端C1连接,客户端C2连接。
        2. C1要向C2发送消息,C1告诉他的进程他想与C2交谈。
        3. 处理C1连接的进程,在共享数组中搜索C2的名称,然后将C1发送的消息写入C2的缓冲区。
        4. 这就是我被卡住的地方..我不知道如何发布C2通知,这是im的新消息。
        5. 我知道任何人都可以照顾,但如果可以的话,我很高兴能得到一些帮助。

          以下是客户端和服务器脚本。

          注意: server.c使用-lptrhead和-lrt编译以绑定共享内存库。

          注意:服务器正确地从函数 get_tcp_listen 获取套接字,您将看到,无需担心这一点。

          我该如何处理这个问题?谢谢!。

          client.c

          #include <stdio.h>
          #include <stdlib.h>
          #include <unistd.h>
          #include <string.h>
          #include <time.h>
          #include <sys/types.h>
          #include <sys/socket.h>
          #include <netinet/in.h>
          #include <arpa/inet.h>
          #include <netdb.h>
          
          #include "socketlib.h" // FOR BINDINGS, GET SOCKET, AND STUFF
          
          #define SERVER_PORT "50000"
          #define CLIENT_PORT "50001"
          #define MAXDATASIZE 256
          #define MAXTIMESIZE 30
          #define NICKSIZE 25
          #define MAXCLIENT 10
          #define MAXMSG 1024
          
          typedef struct{
              char nick[NICKSIZE];        // NICK
              char ip[NI_MAXHOST];        // IP
              char port[NI_MAXSERV];      // PORT
              char connTime[MAXTIMESIZE]; // TIMESTAMP
              int connected;              // STATE
              pid_t pidConn;              // PROCESS PID 
              char *msg;          // MSG BUFFER
          }connData;
          
          
          int main (int argc, char **argv) {
          
              // GET SOCKET
              int sockfd;
              if ((sockfd = get_tcp_connect(argv[1], SERVER_PORT, CLIENT_PORT)) == -1) {
                  fprintf(stderr, "Error client: client_connect\n");
                  exit(1);}
              ///////////////////////////////////////////////////////////////////////
              time_t ltime;
              ltime = time(NULL);
              char timeStamp[MAXTIMESIZE];
              strcpy(timeStamp,ctime(&ltime));
              printf("\n%s\n", timeStamp);
          
              // GET MY IP : PORT
              char ip_num[NI_MAXHOST];
              char port_num[NI_MAXSERV];
              get_socket_addr(sockfd, ip_num, port_num);
              get_peer_addr(sockfd, ip_num, port_num);
              ///////////////////////////////////////////////////////////////////////
          
          
              // WELLCOME MSG FROM SERVER
              char *well = (char*) malloc(MAXDATASIZE); int numbytes;
              if ((numbytes = recv(sockfd, well, MAXDATASIZE-1, 0)) == -1) {
                      fprintf(stderr, "Error client: recv WELLCOME\n");
                      exit(1);
              }
              well[numbytes] = '\0'; printf("%s\n", well); free(well);
              //////////////////////////////////////////////////////////////////////
          
          
              // SEND NICK TO SERVER
              char nick[NICKSIZE];
              printf("\nEnter your NickName (25 chars): "); scanf("%s",nick); 
              if(send(sockfd, nick, NICKSIZE, 0) == -1){
                  fprintf(stderr,"Error client: send NICK\n");
                  exit(1);
              }
              ///////////////////////////////////////////////////////////////////////
          
          
              // GET CONNECTED USERS LIST FROM SERVER
              int cantClients = 0; // FIRST: QUANTITY OF USERS
              if (recv(sockfd, &cantClients, sizeof(int), 0) == -1) {
                  fprintf(stderr, "Error client: recv CANT CLIENTs\n");
                  exit(1);
              }
              connData *tmpCl = (connData *) malloc(sizeof(connData)*MAXCLIENT);
              if (recv(sockfd, tmpCl, sizeof(connData)*MAXCLIENT, 0) == -1) {
                  fprintf(stderr, "Error client: recv ARRAY CLIENTS\n");
                  exit(1);
              }
          
              printf("\n****\tConnected Users\t****\n");
              int i;  
              for(i = 0; i < cantClients; i++){
                  if(tmpCl[i].connected == 1){
                      printf("\nNick: %s\n", tmpCl[i].nick); 
                      printf("IP: %s\n", tmpCl[i].ip);
                      printf("PORT: %s\n", tmpCl[i].port); 
                      printf("Time: %s", tmpCl[i].connTime);
                      printf("Connected: %d\n", tmpCl[i].connected);
                      printf("PID: %d\n", tmpCl[i].pidConn);
                      printf("**********************************\n");
                  }
              } free(tmpCl);
              ///////////////////////////////////////////////////////////////////////
          
          
              // THE CLIENT PROCESS WAITS UNTIL THE USER TYPES A COMMAND
              char *comm = (char*)malloc(MAXDATASIZE);
              printf("\nEnter one option: "); 
              printf("\n\t-> clientlist TO SEE THE LIST OF CONNECTED CLIENTS\n");
              printf("\t-> sendchat TO SEND A MESSAGE\n");
              printf("\t-> quit_ TO QUIT CHAT\n>> ");
              scanf("%s",comm);
          
              int exitvar = 0;
              while(exitvar == 0){
                      // PARA TRAER DATOS DEL SERVIDOR, ENVIO EL COMANDO, Y ME QUEDO ESPERANDO
                      if(send(sockfd, comm, MAXDATASIZE-1, 0) == -1){
                          fprintf(stderr,"Error client: send\n");
                          exit(1);
                      }
          
                      if(strcmp(comm,"clientlist") == 0){
                          // GET CONNECTED USERS LIST FROM SERVER
                          connData *tmpCl = (connData *) malloc(sizeof(connData)*MAXCLIENT);
                          if (recv(sockfd, tmpCl, sizeof(connData)*MAXCLIENT, 0) == -1) {
                              fprintf(stderr, "Error client: recv ARRAY CLIENT\n");
                              exit(1);
                          }
                          printf("\n****\tConnected Users\t****\n"); int i;
                          cantClients = (unsigned) sizeof(*tmpCl) / (unsigned) sizeof(connData);
                          for(i = 0; i < MAXCLIENT; i++){
                              if(tmpCl[i].connected == 1){
                                  printf("\nNick: %s\n", tmpCl[i].nick); 
                                  printf("IP: %s\n", tmpCl[i].ip);
                                  printf("PORT: %s\n", tmpCl[i].port); 
                                  printf("Time: %s", tmpCl[i].connTime);
                                  printf("Connected: %d\n", tmpCl[i].connected);
                                  printf("PID: %d\n", tmpCl[i].pidConn);
                                  printf("**********************************\n");
                              }
                          } free(tmpCl);
                      }else if(strcmp(comm,"sendchat") == 0){
                          printf("To whom you want to talk?... ");
                          char *chatNick = (char *) malloc(NICKSIZE); 
                          fgets(chatNick, NICKSIZE, stdin); 
                          fgets(chatNick, NICKSIZE, stdin); 
          
                          if((strlen(chatNick)>0) && (chatNick[strlen(chatNick)-1] == '\n') ){
                              chatNick[strlen(chatNick)-1] = '\0';
                          }
          
                          if(send(sockfd, chatNick, NICKSIZE, 0) == -1){
                              fprintf(stderr, "Error client: send CHAT NICK\n");
                          } 
          
                          printf("Type your message...\n");
                          char *chat_msg = (char *) malloc(MAXMSG); 
                          fgets(chat_msg,MAXMSG,stdin) ;
          
                          if((strlen(chat_msg)>0) && (chat_msg[strlen(chat_msg)-1] == '\n') ){
                              chat_msg[strlen(chat_msg)-1] = '\0';
                          }
          
                          if(send(sockfd, chat_msg, MAXMSG, 0) == -1){
                              fprintf(stderr, "Error client: send CHAT\n");
                          }
          
                          free(chatNick);
                          free(chat_msg);
          
          
                      }else{
                          char *buf = (char*) malloc(MAXDATASIZE); int numbytes;
                          if ((numbytes = recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
                              fprintf(stderr, "Error client: recv\n");
                              exit(1);
                          }
                          buf[numbytes] = '\0'; printf("-> %s\n", buf);
                          free(buf);
                      }
          
                      if(strcmp(comm, "quit_") != 0){
                          free(comm); comm = (char*)malloc(MAXDATASIZE);
                          printf("\nWhats next?... "); scanf("%s",comm); 
                      }else{
                          close(sockfd);
                          exitvar = 1;
                      }
              }
          
              return 0;
          }
          

          server.c

          #include <stdio.h>
          #include <stdlib.h>
          #include <unistd.h>
          #include <string.h>
          #include <signal.h>
          #include <sys/mman.h>
          #include <fcntl.h>
          #include <sys/types.h>
          #include <sys/wait.h>
          #include <sys/socket.h>
          #include <netinet/in.h>
          #include <arpa/inet.h>  
          #include <netdb.h>
          #include <time.h>
          #include "socketlib.h" 
          #include <semaphore.h>
          
          #define SERVER_PORT "50000"
          #define BACKLOG 10 
          #define MAXDATASIZE 256
          #define NICKSIZE 25
          #define MAXCLIENT 10
          #define MAXTIMESIZE 30
          #define MAXMSG 1024
          
          // ESTRUCTURA QUE MANEJARA LA LISTA DE CLIENTES
          typedef struct{
              char nick[NICKSIZE];        // NICK
              char ip[NI_MAXHOST];        // IP
              char port[NI_MAXSERV];      // PORT
              char connTime[MAXTIMESIZE]; // TIMESTAMP
              int connected;              // STATE
              pid_t pidConn;              // PROCESS PID 
              char *msg;          // MSG BUFFER
          }connData;
          
          
          // NOT ZOMBIE PROCESSES
          void sigchld_handler(int s) {
              while (waitpid(-1, NULL, WNOHANG) > 0);
          }
          
          connData *client;
          int *id; 
          
          int main (int argc, char **argv) {
          
          
              // THE ARRAY OF CLIENTS IS SHARED BETWEEN THE PROCESSES
              int smid = shm_open("shm1", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
              ftruncate(smid, sizeof(connData)*MAXCLIENT);
          
              // JUST FOR MAXCLIENT 10 CLIENTS AT THE MOMMENT
              client = mmap(NULL, sizeof(connData)*MAXCLIENT, PROT_READ | PROT_WRITE, MAP_SHARED, smid, 0);
              sem_t *sem; sem = sem_open("sem1", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 1);
          
          
              // THE ARRAY INDEX IS ALSO SHARED
              int smid2 = shm_open("shm2", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
              ftruncate(smid2, sizeof(int));
          
              id = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, smid2, 0);
              sem_t *sem2; sem2 = sem_open("sem2", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 1);
          
              sem_wait(sem2);
              *id = 0;
              sem_post(sem2);
          
          
              // CONN CONFIG  
              struct sigaction sa;
              sa.sa_handler = sigchld_handler; 
              sigemptyset(&sa.sa_mask);
              sa.sa_flags = SA_RESTART;
          
              if (sigaction(SIGCHLD, &sa, NULL) == -1) {
                  fprintf(stderr, "Error server: sigaction\n");
                  exit(1);
              }
          
              int sockfd; // LISTENER
              if ((sockfd = get_tcp_listen(SERVER_PORT, BACKLOG)) == -1) {
                  fprintf(stderr, "Error get_tcp_listen\n");
                  exit(1);
              }
              printf("server: waiting for connections...\n");
          
              char ip_num[NI_MAXHOST];
              char port_num[NI_MAXSERV];
              get_socket_addr(sockfd, ip_num, port_num);
              //////////////////////////////////////////////////////////////////
          
          
              while (1) {
          
                  // BLOCKS UNTIL SOMEONE REQUEST CONN
                  int new_fd;
                  if ((new_fd = accept(sockfd, NULL, NULL)) == -1) {
                      fprintf(stderr, "Error server: accept\n");
                      continue;}
                  ////////////////////////////////////////////////////////
          
                  // IP:PORT OF JUST CONNECTED USER
                  get_socket_addr(new_fd, ip_num, port_num);      
                  get_peer_addr(new_fd, ip_num, port_num);
                  printf("server: got connection from: %s, %s\n", ip_num, port_num);
                  ////////////////////////////////////////////////////////
          
                  // TIMESTAMP OF USER CONN
                  time_t ltime; ltime = time(NULL);
                  char timeStamp[MAXTIMESIZE]; strcpy(timeStamp,ctime(&ltime));
                  ////////////////////////////////////////////////////////////////////////
          
          
                  // WELLCOME MESSAGE SENT TO THE CLIENT
                  char *well = (char*) malloc(MAXDATASIZE);
                  if (send(new_fd, "Wellcome to the Chat Service!!\n", MAXDATASIZE-1, 0) == -1) {
                      fprintf(stderr, "Error sending WELLCOME\n");
                  } free(well);
                  ///////////////////////////////////////////////////////////////
          
                  // SAVES IN THE ARRAY OF CLIENTS, THE DATA OF THE CLIENT THAT JUST CONNECTED
                  int idTmp1;
                  sem_wait(sem2);
                  idTmp1 = *id;
                  sem_post(sem2);
          
                  if(sem_wait(sem) == 0){
                      strcpy(client[idTmp1].ip, ip_num);  // IP
                      strcpy(client[idTmp1].port, port_num); // PORT
                      strcpy(client[idTmp1].connTime, timeStamp); // TIMESTAMP
                      client[idTmp1].connected = 1;
                  }else{
                      fprintf(stderr, "Error SEM_WAIT\n");
                  }
                  sem_post(sem);  
          
                  sem_wait(sem2); (*id)++; sem_post(sem2);        
          
                  //////////////////////////////////////////////////////////////
          
          
                  // FORKS A PROCESS TO DEAL WITH THE JUST CONNECTED USER
                  if (fork() == 0) { 
                      close(sockfd); // CLOSES THE FATHERS SOCKET
                      int numbytes = 0;
          
                      // SAVES THE NICK IN THE ARRAY
                      char userNick[NICKSIZE];
                      if(( numbytes = recv(new_fd, userNick, NICKSIZE, 0)) == -1){
                          fprintf(stderr,"Error rcv\n");
                      } userNick[numbytes-1] = '\0';
          
                      int idTmp2;
                      sem_wait(sem2);
                      pid_t pidAct = getpid(); // PID OF THE NEW CREATED FORK 
                      idTmp2 = *id;   // ID OF THE USER
                      idTmp2--;
                      strcpy(client[idTmp2].nick,userNick); 
                      client[idTmp2].pidConn = pidAct;
                      idTmp2 = *id;
                      sem_post(sem2);
                      //////////////////////////////////////////////////////////////
          
          
                      // SENDS THE LIST OF CONNECTED CLIENTES
                      if (send(new_fd, id, sizeof(int), 0) == -1) {
                          fprintf(stderr, "Error send ID\n");
                      }
                      if (send(new_fd, client, sizeof(connData)*MAXCLIENT, 0) == -1) { // SEND THE WHOLE LIST
                          fprintf(stderr, "Error send LIST\n");
                      }
                      //////////////////////////////////////////////////////////////
          
                      // THE FORK WAITS SOME COMMAND OF THE USER
                      char *comm = (char*)malloc(MAXDATASIZE);
                      if( (numbytes = recv(new_fd, comm, MAXDATASIZE-1, 0)) == -1){
                          fprintf(stderr,"Error rcv COMMAND\n");          
                      } 
                      comm[numbytes] = '\0';
          
                      // THE FORK ENTERS IN A LOOP WAITING COMMANDS
                      int wait = 0;
                      while(wait == 0){
          
                          if(strcmp(comm,"clientlist") == 0){
                              if (send(new_fd, client, sizeof(connData)*MAXCLIENT, 0) == -1) {
                                  fprintf(stderr, "Error send CLIENT LIST\n");
                              }
          
                          }else if(strcmp(comm,"sendchat") == 0){
                              char *chatNick = (char *) malloc(NICKSIZE); // WAIT FOR THE CLIENT TO TALK TO
                              if(  (numbytes = recv(new_fd,chatNick, NICKSIZE, 0)) == -1){
                                  fprintf(stderr,"Error server rcv CHAT NICK\n");
                              } chatNick[numbytes-1] = '\0';
          
                              char *chatmsg = (char *)malloc(MAXMSG); // WAIT FOR MSG
                              if((numbytes = recv(new_fd, chatmsg, MAXMSG, 0)) == -1){
                                  fprintf(stderr,"Error server rcv CHAT\n");
                              } chatmsg[numbytes-1] = '\0';
          
                              int client_id;
                              sem_wait(sem2);
                              for(client_id = 0; client_id < *id; client_id++){
                                  if(strcmp(client[client_id].nick, chatNick) == 0){
                                      if(client[client_id].msg != NULL){
                                          free(client[client_id].msg);
                                      }
                                      client[client_id].msg = (char * )malloc(MAXMSG); // COPY THE MESSAGE TO THE DESIRED USER
                                      strcpy(client[client_id].msg, chatmsg);
                                      printf("\nTHE MESSAGE TO: %s IS %s\n", client[client_id].nick, client[client_id].msg);
                                  }
                              }
                              sem_post(sem2);
          
                              /*
                                  HERE I HAVE THE NICK, SAY, 'client1' OF THE CLIENT TO WHICH I WANT TO TALK.
                                  THE MSG NOW ITS IN HIS MSG BUFFER LIKE ABOVE.
          
                                  HOW CAN I NOTICE THE FORKED PROCESS HANDLING THE CONNECTION of 'client1'
                                  TO READ THE MESSAGE ?
          
                              */
          
                              free(chatmsg);
                              free(chatNick);
          
                          }else if(strcmp(comm,"quit_") == 0){ 
                              if (send(new_fd, "Byee!!", MAXDATASIZE-1, 0) == -1) {
                                  fprintf(stderr, "Error send EXIT\n");
                              }
                              wait = 1; // FOR EXIT AND CLOSE THE SOCKET
          
                          }else{
                              if (send(new_fd, "Invalid option!", MAXDATASIZE-1, 0) == -1) {
                                  fprintf(stderr, "Error send INVALID\n");
                              }
                          }
          
                          if(wait == 0){
                              // WHEN THE FORKED PROCESS HAS FULFILL THE USERS REQUEST, IT JUST WAITS FOR OTHER REQUEST
                              free(comm); comm = (char*)malloc(MAXDATASIZE);
                              if((numbytes = recv(new_fd, comm, MAXDATASIZE-1, 0)) == -1){
                                  fprintf(stderr,"Error rcv REQUEST\n");          
                              } comm[numbytes] = '\0';
                          }   
                      }
                      if(munmap(client,sizeof(connData)*MAXCLIENT) != 0){ printf("ERROR FREEING MEM\n");}
                      sem_unlink("sem1"); shm_unlink("shm1");
                      printf("Connection ended with %d \n", new_fd);
                      close(new_fd);  exit(0);
                  }
                  printf("Keep waiting connections.....\n");
                  close(new_fd); // SOCKET DEL ACCEPT, DEL CLIENTE QUE SE HABIA CONECTADO
                  //////////////////////////////////////////////////////////////////////////////
              }
          
              if(munmap(client,sizeof(connData)*MAXCLIENT) != 0){ printf("ERROR FREEING MEM\n");}
          
              sem_unlink("sem1");
              shm_unlink("shm1");
          
              return 0;
          }
          

2 个答案:

答案 0 :(得分:3)

我首先要注意fork()和共享内存不是创建聊天服务器的最佳或最简单的方法;如果您有选项,我建议以不同的方式(例如,通过单个进程中的多个线程,甚至是单个线程和select())。

假设你被要求使用这种方法(例如,因为它是在课堂作业中规定的,或者某种东西),但是......你所缺少的是IPC通知机制,即(如你所说)一种方式进程C2注意到进程C1有一些数据供C2处理。

有几种方法可以实现通知......快速而肮脏的方式(可能足以完成类分配)只是让每个进程轮询共享内存区域;例如让每个进程每100毫秒检查一次共享内存区域,看看自上次以来是否有任何变化。在这种情况下,C1可能会将一些新数据写入共享内存区域,然后在写入时在共享内存区域中递增一个整数值。下次C2唤醒以检查整数时,可以注意到整数的值与前一次检查的值不同,并将其视为共享内存区域中有新数据供其处理的提示。 (旁注:当使用共享内存时,你应该以某种方式序列化对共享内存区域的访问,否则你可能会遇到竞争条件,例如C2在开始写入内存的同时开始读取内存。这种情况的症状将是一个系统99.999%的时间正常工作,但当时机“恰到好处”时,偶尔会做一些奇怪/错误的事情。)

但是,如果你想要一种不那么强硬的通知方法(即不会每周7天,每天24小时不占用CPU周期,并且每次通过服务器都不会造成不必要的100mS延迟),那么你需要选择通知机制。一种机制是使用(可称为错误的)kill()系统调用来向C2的进程发送UNIX信号;然后C2需要安装一个信号处理程序,使其在收到该类型的信号时做正确的事情。

但是如果你想避免使用Unix信号(并且我试图避免使用它们,因为它们相当古怪和丑陋),你需要一种更温和的机制,通过它可以唤醒C2进程(IPC通知是收到的)或(收到I / O数据),无论先发生哪种情况......一个天真的阻塞 - I / O调用机制是不够的,因为它只允许你的进程等待一个或另一个,但不是两个。获得两者的好方法是使用select()或poll()同时监视两个套接字:一个套接字是到客户端的TCP连接,另一个套接字是UDP套接字,该进程专门设置为接收IPC通知。每个分叉进程都设置一个监听特定端口的UDP套接字,当C1想要唤醒C2时,C1通过发送()将一个UDP数据包发送到C2的UDP端口来实现。 (UDP数据包的内容无关紧要,因为它的唯一目的是使C2从select()返回,并且由于UDP套接字选择为准备读取,因此C2知道从中读取数据包UDP套接字,丢弃数据包,然后检查共享内存区域以获取新数据。

(当然,一旦你完成了所有这些,你可能会发现C1更容易在UDP数据包本身中简单地包含C2的数据,因此C2不必与潜在的共享内存区域混淆,但这取决于你)

答案 1 :(得分:1)

你差不多完成@Emiliano,这也是我被困一次的原因;)。

嗯,你有一些选择可以告诉其他进程有关消息。

<强> 1。你总是寻找自己的消息缓冲区(这很糟糕,耗费大量CPU并且也是一个坏主意)

进程C1总是在共享内存中查找C1,它自己的缓冲区并检查是否有新消息,并发送给客户端。

<强> 2。您使用信号(优于1)

一个。客户端C2为C1发送消息。

湾进程C2将消息存储在共享内存上的C1缓冲区中(如果我正确理解了您的共享内存结构)

℃。进程C2向C1发送一个信号,通知我已经在你的缓冲区中为你发了一条消息。(在这种情况下,你需要知道哪个pid处理哪个客户端)

d。从进程获取信号后,C1检查其缓冲区并发送给其客户端。

修改 看来你的信号有问题。 这是一个显示信号发送/捕获的简单片段。

recvsig.c

static void handler(int sig, siginfo_t *si, void *data)
{
    printf("%s = %d\n", "Got a signal, signal number is ", sig);

    //you can also code here what you want, after getting a signal
}

void init_signal()
{

    struct sigaction act;

    act.sa_sigaction = handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;

    sigaction(SIGRTMIN + 1, &act, NULL);

}

void main(int argc, char **argv)
{

    printf("%s %d\n", "PID", getpid());

    init_signal();

    while(1)
    {
        pause();
        {
            printf("%s\n", "Received a signal");
            //code here anything after you got signal
        }
    }

    return;
}

sendsig.c

void main(int argc, char **argv)
{

    int pid = atoi(argv[1]);


    while(1)
    {
        sleep(5);
        {
            kill(pid, SIGRTMIN+1);
            printf("%s %d\n", "Sent a signal to ", pid);
        }
    }

    return;
}

在您的程序中,在每个分叉子进程后调用init_signal()。 确保您管理所有分叉进程+连接客户端的pid列表。

使用kill()表示正确的pid。