UNIX C - Kolejki komunikatw IPC - komunikator

0

Witam wszystkich forumowiczów,
Nie wiem czy umieściłem post w odpowiednim miejscu lecz mam prośbę o pomoc. Chcę wykonać program do komunikacji pod UNIXem pomiędzy różnymi terminalami. Przerabiając znaleziony w sieci kod, napotkałem błąd z którym nie potrafię sobie poradzić. Otóż chciałem dodać po wywołaniu programu **sender.c ** możliwość ustalenia przez każdego z osobna swojej nazwy użytkownika aby ta wyświetlana była przed każdą wiadomością. Otóż nie wiem czemu program wychwytuję mi błąd podczas wpisywania jakiejkolwiek nazwy użytkownika wyrzucając error w tym miejscu :

 if (msgsnd (msqid2, &some_data, BUF2, 0) == -1)
    {
      perror ("msqid2 error");
      exit (EXIT_FAILURE);
    }

Chciałbym jeszcze spytać o realizację tego programu w dwie strony - aby obydwie strony mogły jednocześnie wysyłać i odbierać, a wszystko żeby było oparte na jednej kolejce komunikatów IPC.

Z góry dzięki za pomoc!

sender.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define BUF 1024
#define BUF2 1024

struct my_msg_st
{
  long int my_msg_type;
  long int my_user_type;
  char some_text[BUFSIZ];
  char user_name[BUFSIZ];
};

int
main ()
{
  int run = 1;
  struct my_msg_st some_data;
  int msqid;
  int msqid2;
  char buffer[BUF];
  char user[BUF2];

  msqid = msgget ((key_t) 1234, 0666 | IPC_CREAT);
  if (msqid == -1)
    {
      perror ("msgget in sendmsg_sysV failed");
      exit (EXIT_FAILURE);
    }
  printf ("msqid = %d", msqid);



  msqid2 = msgget ((key_t) 1235, 0666 | IPC_CREAT);
  if (msqid2 == -1)
    {
      perror ("msgget in sendmsg_sysV failed");
      exit (EXIT_FAILURE);
    }
  printf ("msqid = %d", msqid2);


  printf ("Podaj nazwę użytkownika:\n");
  fgets (user, BUF2, stdin);
  some_data.my_user_type = 1;
  strcpy (some_data.user_name, user);

  if (msgsnd (msqid2, &some_data, BUF2, 0) == -1)
    {
      perror ("msqid2 error");
      exit (EXIT_FAILURE);
    }

  if (strncmp (user, "end", 3) == 0)
    {
      run = 0;
    }

  while (run)
    {

      printf ("Enter some text:");
      fgets (buffer, BUF, stdin);
      some_data.my_msg_type = 1;
      strcpy (some_data.some_text, buffer);

      if (msgsnd (msqid, &some_data, BUF, 0) == -1)
	{
	  perror ("msgsnd in sendmsg_sysV failed");
	  exit (EXIT_FAILURE);
	}


      if (strncmp (buffer, "end", 3) == 0)
	{
	  run = 0;
	}
    }
  exit (EXIT_SUCCESS);
} 

reciver.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

struct my_msg_st
{
  long int my_msg_type;
  long int my_user_type;
  char some_text[BUFSIZ];
  char user_name[BUFSIZ];
};

int
main ()
{
  int run = 1;
  struct my_msg_st some_data;
  int msqid;
  int msqid2;
  long int msg_to_recv = 1;

  msqid = msgget ((key_t) 1234, 0666 | IPC_CREAT);
  if (msqid == -1)
    {
      perror ("msgget in recvmsg_sysV failed");
      exit (EXIT_FAILURE);
    }
  printf ("msqid= %d", msqid);


  msqid2 = msgget ((key_t) 1235, 0666 | IPC_CREAT);
  if (msqid2 == -1)
    {
      perror ("msgget in recvmsg_sysV failed");
      exit (EXIT_FAILURE);
    }
  printf ("msqid2= %d", msqid2);

  if (msgrcv (msqid2, &some_data, BUFSIZ, msg_to_recv, 0) == -1)
    {
      perror ("msgrcv in recvmsg_sysV failed");
      exit (EXIT_FAILURE);
    }

  if (strncmp (some_data.user_name, "end", 3) == 0)
    {
      run = 0;
    }


  while (run)
    {
      if (msgrcv (msqid, &some_data, BUFSIZ, msg_to_recv, 0) == -1)
	{
	  perror ("msgrcv in recvmsg_sysV failed");
	  exit (EXIT_FAILURE);
	}

      printf ("%s wrote: %s", some_data.user_name, some_data.some_text);


      if (strncmp (some_data.some_text, "end", 3) == 0)
	{
	  run = 0;
	}

    }

  if (msgctl (msqid, IPC_RMID, 0) == -1)
    {
      perror ("msgctl in recvmsg_sysV failed");
      exit (EXIT_FAILURE);
    }

  if (msgctl (msqid2, IPC_RMID, 0) == -1)
    {
      perror ("msgctl in recvmsg_sysV failed");
      exit (EXIT_FAILURE);
    }


  exit (EXIT_SUCCESS);
} 
0

Nie znam się na tym, ale z tego co wyczytałem w manualu, problem tkwi w braku inicjacji my_msg_type. Według mauala musi to być liczba dodatnia.
Poza tym wydaje mi się, że przesyłanie stringów to zły pomysł, lepiej wysyłać zmienną liczbową np. int. Proces odczytujący zamieni numer komunikatu na string i go wyświetli (oczywiście sam musisz to obsłużyć). Dodatkowo wielkość komunikatu w kolejce jest ograniczona przez MSGMAX. Sprawdź w linux/msg.h ile maksymalnie bajtów może zawierać komunikat/wiadomość.

Kolejna sprawa to Twoje msgsnd (msqid2, &some_data, BUF2, 0)
w prototypie funkcji wygląda to tak int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz, int msgflg );
gdzie według manuala msgz to rozmiar wiadomości - długość typu, więc BUF2 powinien być obliczony dla Twojego przykładu:
BUF2 = sizeof(struct my_msg_st) - sizeof(long int);

1 użytkowników online, w tym zalogowanych: 0, gości: 1