LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Please help:program hang stuck there signal handling on POSIX Message Queue UNIX C pr (https://www.linuxquestions.org/questions/programming-9/please-help-program-hang-stuck-there-signal-handling-on-posix-message-queue-unix-c-pr-886397/)

ouou 06-14-2011 10:20 PM

Please help:program hang stuck there signal handling on POSIX Message Queue UNIX C pr
 
in a single main() function,so need signal handling. Use Posix Message Queue IPC mechanism , can ignore the priority and other linked list message,to implement the scenario:

dwhitney67 06-14-2011 11:38 PM

I must say I have a hard time understanding why you are continuously opening and closing the message queue. Perhaps inefficiency is a vague concept to you.

I wrote a simpler program, albeit without the signal handling capabilities that you have in your program. Perhaps you can glean some ideas from this little app:
Code:

#define _XOPEN_SOURCE 600  /* for mq_timedreceive() */
#include <time.h>

#include <mqueue.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>


bool quit = false;


void strip_newline(char* str);
void sigHandler(int sig);


int main(int argc, char** argv)
{
  if (argc != 2)
  {
      fprintf(stderr, "Usage:  %s /qname\n", argv[0]);
      return -1;
  }

  char* qname = argv[1];
  int  qflags = O_RDWR;
  char  msg[80];
  pid_t pid = -1;
  mqd_t qid = -1;

  signal(SIGINT, sigHandler);

  if ((pid = fork()) == 0)
  {
      /* child (ie. client) */

      mqd_t qid = mq_open(qname, qflags);

      if (qid == -1)
      {
        perror("Failed to open the message queue");
        return -1;
      }

      do
      {
        printf("Client: ");
        fgets(msg, sizeof(msg) - 1, stdin);
        strip_newline(msg);

        if (mq_send(qid, msg, strlen(msg), 0) == -1)
        {
          perror("Failed to send msg");
        }

        if (strlen(msg) > 0)
        {
            struct timespec ts = {time(0) + 5, 0};  // 5 seconds into the future

            ssize_t rtn = mq_timedreceive(qid, msg, sizeof(msg), NULL, &ts);

            if (rtn != -1)
            {
              msg[rtn] = '\0';
              printf("%s\n", msg);
            }
            else
            {
              printf("Hmmm, I guess no one is home.\n");
            }
        }
      } while (!quit);
  }
  else if (pid != -1)
  {
      /* parent (ie. server) */

      mode_t qmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
      struct mq_attr qattr;

      qflags |= O_CREAT;

      qattr.mq_flags  = 0;
      qattr.mq_maxmsg  = 10;
      qattr.mq_msgsize = sizeof(msg);
      qattr.mq_curmsgs = 0;

      mqd_t qid = mq_open(qname, qflags, qmode, &qattr);

      if (qid == -1)
      {
        perror("Cannot open message queue");
        return -1;
      }

      do
      {
        ssize_t rtn = mq_receive(qid, msg, sizeof(msg), NULL);

        if (rtn != -1)
        {
            msg[rtn] = '\0';

            if (strcasecmp(msg, "knock knock") == 0)
            {
              strcpy(msg, "Server: Who's there?");

              if (mq_send(qid, msg, strlen(msg), 0) == -1)
              {
                  perror("Failed to send response message");
              }
            }
        }
        else
        {
            perror("Failed to receive message");
        }
      } while (!quit);
  }
  else
  {
      perror("Cannot fork child");
      return -1;
  }

  mq_close(qid);
  mq_unlink(qname);

  return 0;
}


void strip_newline(char* str)
{
  char* nl = strchr(str, '\n');

  if (nl)
  {
      *nl = '\0';
  }
}


void sigHandler(int sig)
{
  quit = true;
}


P.S. Normally I would not combine the client and server code into one source file. I would normally implement these in separate files, and create two executables.


All times are GMT -5. The time now is 12:19 PM.