0

I have two programs: server.c, and c1.c. Server should be running infinitely, and other programs, like c1.c, should send the number to the server, and get the square of that number as a server answer. The problem with my two programs is that server calculates number correctlly, c1 reads from the message queue without errors, but it does not save the number to the struct.

server.c:

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

#define LAST_MESSAGE 255 
int main()
{
    int msqid; 
    char pathname[] = "server.c";
    key_t key; 
    int len, maxlen;
    struct mymsgbuf
    { 
        long mtype;
        int pid;
        int num;
    } mybuf;
    if((key = ftok(pathname,0)) < 0){
        printf("Can\'t generate key\n");
        exit(-1);
    }
    if((msqid = msgget(key, 0666 | IPC_CREAT)) < 0){
        printf("Can\'t get msqid\n");
        exit(-1);
    } 

    //SERVER

    while(1){
        maxlen = sizeof(mybuf.num) + sizeof(mybuf.pid);
        if( len = msgrcv(msqid, (struct msgbuf *) &mybuf, maxlen, 1, 0) < 0){
            printf("Can\'t receive message from queue\n");
            exit(-1);
        }
        printf("Got number from process (#%d): '%d'", mybuf.pid, mybuf.num);

        mybuf.mtype=mybuf.pid;
        int answer = (mybuf.num * mybuf.num);
        printf("Calculating... %d*%d = %d\n", mybuf.num, mybuf.num, answer);
        mybuf.num = answer;
        printf("mybuf.num=%d\n", mybuf.num);
        printf("Sending answer to process (#%d).\n", mybuf.pid);
        if (msgsnd(msqid, (struct msgbuf *) &mybuf, len, 0) < 0){
            printf("Can\'t send message to queue\n");
            msgctl(msqid, IPC_RMID, (struct msqid_ds *) NULL);
            exit(-1);
        }
        printf("Sent answer to process (#%d).\n", mybuf.pid);
    }
    return 0; 
}

c1.c:

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

#define LAST_MESSAGE 255 
int main()
{
    int msqid; 
    char pathname[] = "server.c";
    key_t key; 
    int len, maxlen;
    struct mymsgbuf
    { 
        long mtype;
        int pid;
        int num;
    } mybuf;
    

    int c1_pid = getpid();
    mybuf.pid = c1_pid;

    if((key = ftok(pathname,0)) < 0){
        printf("Can\'t generate key\n");
        exit(-1);
    }
    if((msqid = msgget(key, 0666 | IPC_CREAT)) < 0){
        printf("Can\'t get msqid\n");
        exit(-1);
    } 

    for (int i=1; i<=5; i++)
    {
        mybuf.num = i;
        mybuf.mtype = 1;
        maxlen = sizeof(mybuf.num) + sizeof(mybuf.pid);
        if (msgsnd(msqid, (struct msgbuf *) &mybuf, maxlen, 0) < 0){
            printf("Can\'t send message to queue\n");
            msgctl(msqid, IPC_RMID, (struct msqid_ds *) NULL);
            exit(-1);
        }
        printf("Process with pid=%d sent the message to the server. number = %d \n", c1_pid, i);
        printf("num=%d pid=%d\n", mybuf.num, mybuf.pid);
        if( len = msgrcv(msqid, (struct msgbuf *) &mybuf, maxlen, c1_pid, 0) < 0){
            printf("Can\'t receive message from queue\n");
            exit(-1);
        }
        printf("Process with pid=%d recieved answer from server. Answer=%d \n", c1_pid, mybuf.num);
        sleep(0.4);
    }
    
}

server.c results:

server.c

c1.c results:

1c.c

What am i doing wrong, and how should i prevent this from happening? Thanks in advance!

Barmar
  • 741,623
  • 53
  • 500
  • 612
kims9
  • 45
  • 1
  • 4
  • I think the client is reading the messages it sent, not the replies from the server. – Barmar Dec 07 '22 at 21:57
  • 1
    Paste data as text not images. Images are nor searchable. – Allan Wind Dec 07 '22 at 22:03
  • 1
    For some reason, the msgrcv call is returning 0 in the server process. Rather than using this value in msgsnd, use the actual size of the data element(s) in msgsnd call in the server. – kjohri Dec 09 '22 at 18:43

0 Answers0