Laboratorium 3

by Paweł Paduch published 2018/12/14 15:08:40 GMT+2, last modified 2018-12-14T15:08:40+02:00
Tworzenie i komunikacja za pomocą łączyPIPE

Łącza PIPE

To laboratorium ma na celu zapoznanie się z zasadą tworzenia łącz nie nazwanych, oraz zasady komunikacji pomiędzy dwoma spokrewnionymi procesami.

    1. Wstęp
      • Łącza komunikacyjne nie nazwane (PIPE) możemy użyć jedynie pomiędzy dwoma spokrewnionymi procesami.
      • tworzymy za pomocą funkcji:
        int pipe(int *filedes);
        • filedes - tablica dwuelementowa
        • filedes[0] - jest deskryptorem pliku otwartym do czytania
        • filedes[1] - jest deskryptorem pliku otwartym do pisania
      • łącza komunikacyjne zwykle używamy do komunikowania się dwóch procesów, ale poniższy przykład będzie na jednym:
        main()
        {
        int pipefd[2],n;
        char buff[100];
        if (pipe(pipefd) <0)
            perror("blad pipe\n");
        printf("read fd = %d, write fd = %d\n",pipefd[0],pipefd[1]);
        if (write(pipefd[1],"hello world\n",12) !=12)
            perror("blad zapisu\n");
        if ((n = read(pipefd[0],buff,sizeof(buff))) <=0)
            perror("blad odczytu\n");
        write(1, buff, n); /* deskryptor pliku=1 wyjscie standardowe */
        exit(0);
        }
    2. Cel
      Napisać program typu klient-serwer który:
      • pobiera od użytkownika nazwę pliku 0,5pkt
      • tworzy łącze nienazwane PIPE 0,5pkt
      • tworzy nowy proces za pomocą funkcji fork (nie popen!) 0,5pkt
      • przesyła do procesu potomnego nazwę pliku. 0,5pkt
      • proces potomny odczytuje plik o podanej nazwie a zawartość (tekst) lub informację o możliwych błędach (np. brak pliku), przesyła do procesu rodzicielskiego (komunikaty o błędzie 0,5pkt)
      • proces rodzicielski wyświetla na standardowym wyjściu co otrzymał od potomka (poprawne przesłanie pliku do 2pkt).
    3. Pomocne funkcje:
      • gets lub fgets
      • perror, strerror
      • read, write
      • fork, wait
      • pipe, close
      • strcat, strlen, strcpy

    4. Uwaga końcowa
      Pamiętać należy o przydziale pamięci na przesyłane komunikaty. Ważny jest też fakt że łącze pipe służy jedynie do przekazywania danych w jedną stronę. Jeżeli chcemy mieć komunikację dwukierunkową trzeba stworzyć 2 łącza. 1 zamknąć u potomka do odczytu a u przodka do zapisu a drugie u potomka do zapisu a u przodka do odczytu. Plik może być dowolnej długości odczytywanie jak i przesyłanie zrealizować w pętli (nie jednokrotny odczyt). Nie używać bezmyślnie memset, nie stosować odczytu po jednym znaku ani kombinacji w stylu przesłania specjalnych znaczków kończących transmisje. Funkcja read jest funkcją synchroniczną.

    5. Sprawozdanie
      Oczywiście nie zapomnijcie o sprawozdaniu.