Kolejka komunikatów - funckja mq_open()

0

Witam, mam do napisania program zawierający dwie funkcje (klient i serwer). W argumentach wywołania programu podajemy nazwę pliku, funkcja klient wysyła tę nazwę serwerowi, serwer otwiera ten plik, czyta jego zawartość i przesyła z powrotem do klienta. Na koniec klient wypisuje otrzymaną zawartość pliku na ekran (stdout). Program ma działać z wykorzystaniem kolejki komunikatów, a dokładnie funkcji mq_open(), która tworzy nową, bądź otwiera istniejącą kolejkę (łącze), aby wysyłać i pobierać dane używamy odpowiednio funkcji mq_send() oraz mq_receive(). No i napisałem kod znajdujący się poniżej, program się kompiluje ale nic nie wypisuje na ekran, w ogóle po uruchomieniu się zawiesza (pojawia się kursor czekający na wpisywanie tekstu z klawiatury ... ). Ktoś wie jak naprawić ten kod? Nie wiem gdzie jest błąd ... Poza tym otwarte kolejki należałoby pozamykać, wiem że trzeba użyć mq_close() , a na koniec mq_unlink(), ale nie wiem czy zrobić to na poziomie klienta i serwera, czy w funkcji main? Z góry dziękuję za pomoc.

#ifndef BIB_H
#define BIB_H
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <mqueue.h>
#define QUEUE_NAME1  "/test_queue1"
#define QUEUE_NAME2  "/test_queue2"
#define MAX_SIZE    1024
#define MSG_STOP    "exit"
#define BUFSIZE 256

/*funkcja klient */
void klient(char *path, mqd_t mq1, mqd_t mq2){
	int n, status;
	char *buf;
	buf = (char*) malloc(BUFSIZE);
        mq_send(mq1, path,  BUFSIZE,0);
        while((n=mq_receive(mq2, buf, BUFSIZE,NULL)) != -1){
		printf("%s", buf);
	}	
}

/*funkcja serwer*/
void serwer(mqd_t mq1, mqd_t mq2){
	int file;
	int n;
	char *buf, *buf2;
	buf = (char*) malloc(BUFSIZE);
	buf2 = (char*) malloc(BUFSIZE);

	/*odczytaj sciezke pliku*/
	mq_receive(mq1,buf,BUFSIZE,NULL);
	/*sprobuj otworzyc plik*/
	if((file = open(buf, O_RDONLY))== -1){
		mq_send(mq2,'\0',2,0);
		exit(1);
	}
	else{
		while((n = read(file, buf2, BUFSIZE)) >= 0){
			mq_send(mq2, buf2, BUFSIZE,0);
		}
	}
	close(file);
}
#endif

#include "bib_mq.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <mqueue.h>
#define QUEUE_NAME1  "/test_queue1"
#define QUEUE_NAME2  "/test_queue2"
#define MAX_SIZE    1024

int main(int argc, char **argv){
    char* path;
    int kod;
    mqd_t mq1,mq2; 
    struct mq_attr attr;

    /*inicjalizacja atrybutow kolejki komunikatow */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = MAX_SIZE;
    attr.mq_curmsgs = 0;

    if(argc!=2){
        printf("zla ilos argumentow\n");
        exit(EXIT_FAILURE);
    }
    path=argv[1];

    mq1 = mq_open(QUEUE_NAME1, O_CREAT | O_RDWR, 0644 ,&attr);
    mq2 = mq_open(QUEUE_NAME2, O_CREAT | O_RDWR,0644,&attr);
    kod = fork();
    if(kod==-1){
        printf("blad funkcji fork\n");
        exit(3);
    }
    else if(kod){ //wartosc zmiennej kod != 0, zatem dotyczy to procesu macierzystego
        klient(path, mq1,mq2);
    }
    else{ //kod = 0, zatem dotyczy to potomka
        serwer(mq1,mq2);
    }
    return 0;
}
0

Może spróbuj otwierać kolejkę po forku?

0

Niestety to nic nie zmienia ...

1

Trochę lepsza wersja:


// mq.c
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <mqueue.h>
#define QUEUE_NAME1  "/test_queue1"
#define QUEUE_NAME2  "/test_queue2"
#define MAX_SIZE    1024

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <mqueue.h>
#define QUEUE_NAME1  "/test_queue1"
#define QUEUE_NAME2  "/test_queue2"
#define MAX_SIZE    1024
#define MSG_STOP    "exit"
#define BUFSIZE 256

/*funkcja klient */
void klient(char *path, mqd_t mq1, mqd_t mq2){
    int n;
    char *buf;

    printf("Klient wysyla\n");
    buf = (char*) malloc(BUFSIZE);
    mq_send(mq1, path,  strlen(path),0);
    printf("Klient odbiera\n");
    while((n=mq_receive(mq2, buf, BUFSIZE,NULL)) != -1){
      printf("Klient odebral: [%s]\n", buf);
    }   
    printf("Klient wychodzi\n");
}

/*funkcja serwer*/
void serwer(mqd_t mq1, mqd_t mq2){
    int file;
    int n;
    char *buf, *buf2;
    printf("Serwer nasluchuje\n");
    buf = (char*) malloc(BUFSIZE);
    buf2 = (char*) malloc(BUFSIZE);

    /*odczytaj sciezke pliku*/
    mq_receive(mq1,buf,BUFSIZE,NULL);
    /*sprobuj otworzyc plik*/
    if((file = open(buf, O_RDONLY))== -1){
        printf("Serwer wysyla #1\n");
        mq_send(mq2,"\0",2,0);
        printf("Serwer wychodzi\n");
        exit(1);
    }
    else{
        printf("Serwer wysyla #n\n");
        while((n = read(file, buf2, BUFSIZE)) >= 0){
            printf("Serwer wysyla #n1\n");
            mq_send(mq2, buf2, BUFSIZE,0);
            printf("Serwer wysyla #n2\n");
        }
    }
    printf("Serwer sie zamyka\n");
    close(file);
}

int main(int argc, char **argv){
    char* path;
    int kod;
    mqd_t mq1,mq2; 
    struct mq_attr attr;

    /*inicjalizacja atrybutow kolejki komunikatow */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = MAX_SIZE;
    attr.mq_curmsgs = 0;

    if(argc!=2){
        printf("zla ilos argumentow\n");
        exit(EXIT_FAILURE);
    }
    path=argv[1];

    mq1 = mq_open(QUEUE_NAME1, O_CREAT | O_RDWR, 0644 ,&attr);
    mq2 = mq_open(QUEUE_NAME2, O_CREAT | O_RDWR,0644,&attr);
    kod = fork();
    if(kod==-1){
        printf("blad funkcji fork\n");
        exit(3);
    }
    else if(kod){ //wartosc zmiennej kod != 0, zatem dotyczy to procesu macierzystego
        klient(path, mq1,mq2);
    }
    else{ //kod = 0, zatem dotyczy to potomka
        serwer(mq1,mq2);
    }
    return 0;
}
// makefile
all:  mq

mq: mq.c
	gcc -Wall -o mq mq.c -lrt
    
clean:
	rm -fr *~ mq

Wynik:

Klient wysyla
Klient odbiera
Klient wychodzi
Serwer nasluchuje
Serwer wysyla #1
Serwer wychodzi

Pokombinuj, ja nie mam już dzisiaj czasu.

Tu masz pokazane jak to mogłoby wyglądać:
https://www.softprayog.in/programming/interprocess-communication-using-posix-message-queues-in-linux

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