====== Aplikacje wielowątkowe ====== ===== Zadanie 1 - Komunikator tekstowy z wieloma klientami ===== Zaimplementuj serwer programu do komunikacji tekstowej (czat) obsługujący wielu klientów równocześnie. Każda aplikacja kliencka po połączeniu z serwerem ma możliwość wysyłania komunikatów, które następnie są przez serwer przekazywane do wszystkich pozostałych połączonych aplikacji klienckich. Przesyłanie komunikatów tekstowych pomiędzy serwerem a aplikacjami klienckimi odbywa się asynchronicznie z wykorzystaniem wielowątkowości. Źródła: * szablon aplikacji serwerowej {{zajecia:winprog_2015_1:src:serwer.cpp}} * przykładowa aplikacja kliencka, którą można wykorzystać do testów {{zajecia:winprog_2015_1:src:czat_klient.cpp}} Zaimplementuj następujące funkcjonalności: * Przycisk ''Run'' * tworzy gniazdo i ustawia je w trybie do nasłuchu. * tworzony główny wątek serwera, który oczekuje na połączenia * Główny wątek serwera: * w przypadku uzyskania połączenia tworzony jest wątek odpowiedzialny za obsługę danych nadchodzących od pojedynczego klienta. * w momencie przekroczenia dozwolonej liczby połączeń uniemożliwia nawiązanie połączenia z kolejnymi klientami * może być przerwany poprzez odpowiedni przycisk (np. ponowne wciśnięcie klawisza ''Run'') * W przypadku nawiązania połączenia tworzony jest osobny wątek obsługujący to połączenie: * oczekuje na nadchodzące komunikaty * w przypadku otrzymania komunikatu rozsyła jego kopię do wszystkich połączonych z serwerem klientów * w przypadku zerwania połączenia zamyka gniazdo związane z tym połączeniem ===== Przydatne funkcje ===== **Obsługa wątków:** * [[https://msdn.microsoft.com/en-us/library/ms682453%28VS.85%29.aspx|CreateThread]] tworzenie wątku * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms686717%28v=vs.85%29.aspx|TerminateThread]] przerywanie działania wątku * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211%28v=vs.85%29.aspx|CloseHandle]] zamyka uchwyt do obiektu (np. do wątku) * [[https://msdn.microsoft.com/en-us/library/ms687032%28v=vs.85%29.aspx|WaitForSingleObject]] * [[https://msdn.microsoft.com/en-us/library/ms687025%28v=vs.85%29.aspx|WaitForMultipleObjects]] **Komunikacja sieciowa:** * plik nagłówkowy ''winsock2.h'' i biblioteka ''WS2_32.lib'' * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms742213%28v=vs.85%29.aspx|WSAStartup]], ''WSACleanup()'' \\ inicjalizacja WinSocket * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506%28v=vs.85%29.aspx|socket]], closesocket(), tworzenie gniazda * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550%28v=vs.85%29.aspx|bind]] kojarzy gniazdo z lokalnym adresem \\ sockaddr_in adres; adres.sin_port=htons(numer_portu); adres.sin_family=AF_INET; adres.sin_addr.s_addr=htonl(INADDR_ANY); bind(gniazdo, &adres, sizeof(adres)); * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms738563%28v=vs.85%29.aspx|inet_addr]] zamienia adres IP z postaci łańcucha znakowego do postaci liczby całkoiwtej * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms738557%28v=vs.85%29.aspx|htons]] i [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms738556%28v=vs.85%29.aspx|htonl]] transfrormacja liczby short/long wymagana przy definiowaniu portu w protokole AF_INET i AF_INET6 * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms739168%28v=vs.85%29.aspx|listen()]] ustawia gniazdo w stanie nasłuchu * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526%28v=vs.85%29.aspx|accept()]] ustanawia połaczenie, zwraca gniazdo łączące z klientem, pozwala na przesyłanie danych za pomocą ''send()'' i ''recv()'' * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms740149%28v=vs.85%29.aspx|send()]] wysyła dane przez gniazdo * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121%28v=vs.85%29.aspx|recv()]] odbiera dane z połacznoego gniazda