L7: Czasopismo literackie#

„Chronicle", renomowane czasopismo literackie, znajduje się obecnie w punkcie krytycznym. Redaktorzy są przeciążeni pracą, zajmując się zgłoszeniami pochodzącymi od zaledwie jednego autora. Właściciel doszedł do wniosku, że problem leży w systemie przyjmowania i dystrybucji tekstów. Czasopismo nadal opiera się na przestarzałej infrastrukturze, aby realizować swoją podstawową działalność: przyjmowanie wierszy i prozy od autorów oraz przekazywanie ich czytelnikom.

Na początek Twoim zadaniem jest stworzenie systemu, który pomoże pojedynczemu redaktorowi (użytkownikowi programu) współpracować z jednym autorem (serwerem TCP netcat) i wieloma czytelnikami (klientami TCP netcat). Właściciel chce przeciążać każdego redaktora pracą z wieloma autorami, więc upewnij się, że system jest skalowalny (wykorzystaj mechanizm multipleksowania).

Program przyjmuje 2 argumenty: \(X\) (port autora, z którym należy się połączyć) oraz \(Y\) (port, z którym powinni połączyć się czytelnicy).

Etapy:#

Etap 1 (6 pkt)#

Skontaktuj się z autorem i zacznij odbierać rozdziały. Autor (serwer netcat) będzie nasłuchiwał na porcie \(X\). Program musi nawiązać z nim połączenie i wyświetlać wszystkie odebrane znaki na STDOUT. Użyj epoll, poll lub select do nasłuchiwania przychodzących danych. Aby zmniejszyć liczbę wywołań systemowych, za każdym razem spróbuj odczytać co najmniej READ_BUFF_SIZE bajtów od autora, ale nie blokuj programu, jeśli dostępna jest mniejsza ilość danych. Program zatrzymuje się dopiero wtedy, gdy autor zamknie połączenie.

Etap 2 (7 pkt)#

Czas udostępnić czytelnikom te wspaniałe dzieła literackie w trybie multiemisji. Zacznij nasłuchiwać połączeń na porcie \(Y\); możesz obsługiwać jednocześnie do MAX_CLIENTS czytelników (w trakcie działania programu może ich być więcej, jeśli niektórzy czytelnicy się rozłączą). Wykorzystaj ten sam mechanizm multipleksowania, co w etapie 1. Dodatkowo pierwszym czytelnikiem jest zawsze terminal — wciąż wypisuj na standardowe wyjście.

Po nawiązaniu połączenia czytelnik będzie otrzymywał wszystkie dane przesyłane przez autora, tak jakby był podłączony bezpośrednio. Czytelnicy mogą się rozłączyć w dowolnym momencie. Rozłączenie nie przerywa odbierania danych od autora ani wysyłania ich do innych czytelników. Nie wysyłaj danych do rozłączonych czytelników.

Etap 3 (7 pkt)#

Współczesne algorytmy mediów społecznościowych przyzwyczaiły czytelników do wyselekcjonowanych treści. Aby być na bieżąco, wdroż system filtrowania treści na żądanie. Odbieraj dane od czytelników (również ze standardowego wejścia), starając się robić to również w blokach o wielkości READ_BUFF_SIZE. Ostatnia litera (można użyć funkcji isalpha()) otrzymana od czytelnika staje się jego filtrem. Należy pamiętać, że oznacza to, iż filtr może zostać zaktualizowany w dowolnym momencie.

Czytelnicy z skonfigurowanym filtrem nie będą otrzymywać danych autora w całości. Zamiast tego będą otrzymywać jedynie niepokrywające się podciągi o długości GREP_LEN (5), zaczynające się od znaku filtrującego. Na przykład, jeśli autor wyśle "aaabacccccahhhjioao\ncalhjkhj", czytelnik z filtrem 'a' otrzyma "aaabaahhhjao\nca". Jeśli podciąg jest krótszy niż GREP_LEN, musi zostać uzupełniony i wysłany dopiero po nadejściu nowych danych.

Etap 4 (4 pkt)#

Rektor ogłosił godziny rektorskie. Po otrzymaniu SIGINT przetwarzanie zostanie zatrzymane, ale nadal konieczne jest zwolnienie zasobów. Przed zakończeniem wyświetl komunikat „Nie daję już rady!!!". Należy pamiętać o możliwych wyścigach!

Kod startowy#