UNIX (2 zadania) POMOCY

0

Witam

Pilnie potrzebuje pomocy nad tymi zadaniami, 21 stycznia mam warunek z tego i zabardzo niekumam unixa,a musze to odda .Jesli ktos by mogł pomoc ,niech da znac.

dzięki i pozdrawiam całe forum

Zadanie W37

Opracować zestaw programów typu producent - konsument realizujących przywykorzystaniu mechanizmu kolejek komunikatów, następujący schematkomunikacji międzyprocesowej:Proces 1: czyta dane (pojedyncze wiersze) ze standardowego strumieniawejściowego i przekazuje je w niezmienionej formie do procesu 2.Proces 2: pobiera dane przesłane przez proces 1. Oblicza ilość znaków wkażdej linii i wyznaczoną liczbę przekazuje do procesu 3.Proces 3: pobiera dane wyprodukowane przez proces 2 i umieszcza je wstandardowym strumieniu wyjściowym. Każda odebrana jednostka danych powinnazostać wyprowadzona w osobnym wierszu.Proces 2 powinien reagować na trzy sygnały wysyłane przez operatora. Sygnał1 powinien powodować zakończenie działania przez wszystkie procesy. Reakcjąna sygnał 2 powinno być wstrzymanie przepływu strumienia danych przezwszystkie procesy. Sygnał 3 powinien powodować wznowienie przepływu danych.Proces 2, po odebraniu sygnału od operatora przekazuje informacje oodebranym poleceniu, wysyłając do pozostałych procesów sygnał 4 orazkomunikat poprzez mechanizm semaforów i pamięci dzielonej. Wszystkie trzyprocesy powinny być powoływane automatycznie z jednego procesu inicjującego.Dobór sygnałów realizujących funkcje sygnałów 1, 2, 3 i 4 można zrealizowaćw sposób dowolny.

Zadanie S6

Opracować aplikację pracującą wg modelu klient-serwer. Klient zwraca się doserwera z wieloma różnymi żądaniami. Należy zaimplementować obsługę dwóchżądań wysyłanych przez klienta i obsługiwanych przez serwer:- żądanie przekazania informacji o UID użytkownika -właścicielaprocesu serwera (można wykorzystać funkcję getuid),- żądanie przekazania statystyki ruchu na zadanym interfejsiesieciowym.Klient powinien w żądaniu określić rodzaj żądania (kod żądania), orazewentualnie inne parametry niezbędne serwerowi do wykonania polecenia, np.nazwę interfejsu sieciowego. Po dostarczeniu odpowiedzi przez serwer, klientpowinien poinformować o jej treści operatora, wyprowadzając stosownekomunikaty do standardowego strumienia wyjściowego. Wartości (parametry)umożliwiające skompletowanie żądania przez klienta powinny być przez niegopobierane częściowo z linii polecenia uruchamiającego proces klienta (np.adres serwera) a częściowo interakcyjnie w czasie pracy procesu klienta (np.nazwa interfejsu).Po stronie serwera należy również obsłużyć przynajmniej dwie sytuacjewyjątkowe. Jedna z nich powinna polegać na podaniu przez klienta nazwyinterfejsu, który nie jest obsługiwany przez system serwera. W takiejsytuacji serwer powinien zwrócić klientowi kod błędu, a klient powinienwyprowadzić do standardowego strumienia diagnostycznego stosowny komunikat.Drugą sytuację wyjątkową i sposób jej obsługi należy zaproponowaćsamodzielnie.Aplikację należy zaimplementować wykorzystując mechanizm zdalnego wywołaniaprocedury (Sun RPC).

pozdrawiam

0

kod do podobnego programu wygląda mniejwięcej jak,moe komus cos wpadnie do głowy .

PLIK Init.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
// korzystasz z tych bibliotek

int main()
{
int pipe_dsc[2]; // deklaracja zmiennych
int pipe_dsc2[2];
int pid, pid2; // int oznacza liczbe
char pipe_read_dsc_str[10];
char napis[20];
char napis2[20];// char to znak
// jak napiszesz char zmienna; - jeden znak;
// jak napiszesz char zmienna[5] - piec znakow

pipe (pipe_dsc);// tworzy pipe, bedzie on pomiedzy procesem1 i procesem2
pid = fork(); // fork() powoduje rozdwojenie dzialajacego programu
// jeden z nich bedzie mial wartosc pid rowna 0,
// a drugi bedzie mial numer drugiego procesu
if (pid == 0) {
// pierwszy program wejdzie tu
printf(" PROCES2: \n");// wyswietl na ekran
//\n oznacza zeby przechodzil do nastepnej linii
close (pipe_dsc[1]); // tu zamykamy deskryptor pipe
// bo pipe otworzyl dwa: jeden do pisania, drugi do czytania
// zamykamy ten do pisania
read(pipe_dsc[0], napis, 4);
// read(pipe_dsc[0] - czytaj z tego pipe, do tablicy napis, maksymalnie
// cztery znaki, poniewaz ten proces spodziewa sie danych od procesu1
// - numeru pid

  pipe(pipe_dsc2);
  // tworzymy drugiego pipe - bedzie on pomiedzy procesem2 i procesem3
  
  pid2=fork(); // tutaj tworzymy proces3
  
  if (pid2 == 0) {
     // tutaj wejdzie jeden program uruchomiony przez drugiego fork()
  printf("PROCES3:\n");	  
  close(pipe_dsc2[1]);  // zamykasz pipe do pisania
      execvp("./proces3",NULL); 
  // execvp - uruchom program proces3 - z linii procesu
  // NULL dla execvp - uruchom ten program bez argumentow
   } else {
     // tutaj wejdzie drugi program uruchomiony przez drugiego fork();
  close(pipe_dsc2[0]);
  // zamykam deskryptor do czytania
      write(pipe_dsc2[1], napis, 4);
  // przesyla procesowi3 pid otrzymany od procesu1
  
  sprintf(napis2, "%d", getpid()); // getpid - zwraca numer procesu2
  // akualnie wykonujacego sie procesu - tutaj: procesu2
  // sprintf - konwersja liczby int na napis - trzeba napisac "%d",
  // ze chcemy skonwertowac inta
      write(pipe_dsc2[1], napis2, 4);
  // przesyla procesowi3 swoj pid
      execvp("./proces2",NULL);
}
  }
} else {  // ten else tyczy sie if (pid == 0)
  // drugi program wejdzie tu
  printf("PROCES1: \n");
  close (pipe_dsc[0]);
  sprintf(napis, "%d", getpid());// zwraca numer procesu1 i konwertuje
  // go na stringa (nasis)
  write(pipe_dsc[1], napis, 4);
  // przesyla procesowi2 pid
  execvp("./proces1",NULL);

}

Plik Proces1

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

int fd;
int kom[10];
int przesylanie = 1;
void a_handler (int signum)
{
if (signum == 4) {
printf("p1 - sygnal4\n");
read(fd, kom, 1);
// w kom bedzie to co przeczytasz z kolejki komunikatow
// czytasz z kolejki komunikatow
kom[1] = '\0'; // to sie robi po to zeby printf wypisal to dobrze
printf("p1 - otrzymalem: %s \n",kom[0]);
if (kom[0] == '3') przesylanie = 1;// przesylaj dane do procesu2
if (kom[0] == '2') przesylanie = 0;// nie przesylaj danych do procesy2
if (kom[0] == '1') {

  unlink("fifo1");// skasuj kolejke komunikatow
  exit(0);      
}

}
}

int main()
{
char bufor[8000];
int ile;
int i;
struct sigaction new;

new.sa_handler = a_handler;
sigemptyset(&new.sa_mask);
new.sa_flags = 0;

printf("PROCES1-plik\n");
sigaction(4, &new, 0);

mknod("fifo1", S_IFIFO | 0666, 0);
fd = open("fifo1", O_NDELAY | O_RDONLY);
// O_RDONLY - bedziesz tylko czytal z kolejki
printf("P1-OK\n");
while (1) {

ile = read(0, bufor, 8000); // read(0 - czytaj z klawiatury (standardowego wejscia)
// maks dlugosc: 8000;
// ile - ilosc przeczytanych bajtow
if (ile > 0 && przesylanie == 1) { // && - and
  printf("P1: Odczytano %s\n", bufor);
  write(4, bufor, ile);
}
// read(x, write(x  - x jest deskryptorem
// 0-wy deskryptor to klawiatura; 1 - monitor ;2 -strumien bledow;
// 3 - nasz pipe

}
}

Proces 2

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>

int fd;
int kom[10];
int przesylanie = 1;

void a_handler (int signum)
{
if (signum == 4) {
printf("p2 - sygnal4\n");
read(fd, kom, 1);
kom[1] = '\0';
printf("p2 - otrzymalem: %s\n", kom);
if (kom[0] == '3') przesylanie = 1;
if (kom[0] == '2') przesylanie = 0;
if (kom[0] == '1') {
unlink("fifo2");
exit(0);
}
}
}

int main()
{
char bufor[8000];
int ile;
int i;
struct sigaction new;

new.sa_handler = a_handler;
sigemptyset(&new.sa_mask);
new.sa_flags = 0;

printf("PROCES2-plik\n");
sigaction(4, &new, 0);
mknod("fifo2", S_IFIFO | 0666, 0);
fd = open("fifo2", O_NDELAY | O_RDONLY);
printf("P2-OK\n");
while (1) {

ile = read(3, bufor, 8000); // read(0 - czytaj z klawiatury (standardowego wejscia)
// maks dlugosc: 8000;
// ile - ilosc przeczytanych bajtow
if (ile > 0 && przesylanie == 1) {
  printf("P2: Odczytano %s\n", bufor);

  for (i=0; i< ile; i++)  // i++ - zwieksz i o jeden
     // i < ile - wywoluj tak dlugo az to bedzie spelnione
    bufor[i] = bufor[i]+1;//
  // wywoluje kolejno:
  // bufor[0] = bufor[0]+1;
  // bufor[1] = bufor[1]+1;
  // bufor[2] = bufor[2]+1;
  // ..
  // bufor[ile] = bufor[ile]+1;


  write(5, bufor, ile);
}
// read(x, write(x  - x jest deskryptorem
// 0-wy deskryptor to klawiatura; 1 - monitor ;2 -strumien bledow;
// 3 - nasz pipe

}
}

Proces 3

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

// zmienne globalne
int pid1, pid2;
int fd1, fd2;

void a_handler (int signum)
// void - funkcja a_handler zwraca "pusta" wartosc
{
if (signum == 1) {
printf("Sygnal1\n");
// fd1, fd2 - deskryptory do kolejek komunikatow
write(fd1, "1",1);// pisze do kolejki komunikatow, napis "1",
// druga jedynka oznacza: napisz maksymalnie 1 znak
write(fd2, "1",1);
kill(pid2,4);// wyslij sygnal o numerze 4 do procesu 2
kill(pid1,4);// wyslij sygnal o numerze 4 do procesu 1
exit(0); // zakoncz program

}
if (signum == 2) {
printf("Sygnal2\n");
write(fd1, "2",1);
write(fd2, "2",1);
kill(pid2,4);
kill(pid1,4);
}
if (signum == 3) {
printf("Sygnal3\n");
write(fd1, "3",1);
write(fd2, "3",1);
kill(pid2,4);
kill(pid1,4);
}
}

int main()
{
char bufor[8000];//deklarujesz tablice na 8000 znakow
int ile; // deklarujesz zmienna "ile"
int i;
char spid1[4];
char spid2[4];
struct sigaction new; // to bedzie potrzebne do oblugi sygnalow
// new - bedzie to struktura do obslugi sygnalow
new.sa_handler = a_handler; // tu ustalasz, ze funkcja uruchamiana
// po otrzymaniu sygnalu to bedzie funkcja a_handler;
sigemptyset(&new.sa_mask); // to bedzie potrzebne do oblugi sygnalow
new.sa_flags = 0; // to bedzie potrzebne do oblugi sygnalow
printf("PROCES3-plik\n");

sigaction(1, &new, 0); // program teraz bedzie obslugiwal sygnal 1
// jesli dostanie ten sygnal to uruchomiona zostanie funkcja a_handler

sigaction(2, &new, 0); // to samo dla sygnalu 2
sigaction(3, &new, 0); // to samo dla sygnalu 3

mknod("fifo1", S_IFIFO | 0666, 0); // tworzy kolejke komunikatow
// - jest to plik specjalny o nazwie fifo1,
// S_IFIFO - chcesz stworzyc fifo, a nie cos innego
// | 0666 - prawa dostepu do kolejki, zeby mozna bylo czytac, pisac do niej
// 0 - bez dodatkowych opcji

mknod("fifo2", S_IFIFO | 0666, 0);
// to samo dla fifo2

fd1 = open("fifo1", O_NDELAY | O_WRONLY);
// open - otwierasz plik fifo1 - czyli ta kolejke
// fd1 - to bedzie jej deskryptor (numer po ktorym mozna sie odwolywac
// do kolejki
// O_NDELAY - zeby sie program nie zatrzymal w tym miejscu
// O_WRONLY - bedziesz tylko pisal do tej kolejki
fd2 = open("fifo2", O_NDELAY | O_WRONLY);

ile = read(4,spid1, 4);
// czytaj od procesu2 pierszy pid

spid1[4] = '\0'; // to jest potrzebne do konwersji
pid1 = atoi(spid1); // konwersja napisu na liczbe
ile = read(4,spid2, 4);
// czworka - numer pipe
// czytaj nastepny pid od procesu2
spid2[4] = '\0';
pid2 = atoi(spid2);

while (1) {

ile = read(4, bufor, 8000); // read(0 - czytaj z klawiatury (standardowego wejscia)
// maks dlugosc: 8000;
// ile - ilosc przeczytanych bajtow
if (ile > 0)
  printf("P3: Odczytano %s\n", bufor); 
  // bufor jest napisem i wypisujesz go na ekran - i po to ten %s
// read(x, write(x  - x jest deskryptorem
// 0-wy deskryptor to klawiatura; 1 - monitor ;2 -strumien bledow;
// 4 - nasz pipe

}
}

0

PLIK Init.c

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
// <font color="red">korzystasz z tych bibliotek</span>

hahahahahah - nie moglem sie oprzec :D

// nie kumam żartu, zwłaszcza, że właśnie tak się pisać powinno, czyżbyś śmiał się ze swojej niewiedzy ? :> [mf]

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