Edytuj stronę Odnośniki Fold/unfold all ODT export Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić. ====== Aplikacje sieciowe i wielowątkowe ====== ===== Zadanie 1 - Komunikator tekstowy z wilowątkowością ===== Zaimplementuj serwer programu do komunikacji tekstowej (czat) obsługujący połączenia w osobnych wątkach. Główny wątek serwera czeka na połączenie. W momencie uzyskania połączenia rozpoczyna odczyt kolejnych napływających komunikatów od klienta i umieszcza je w polu tekstowym (kontrolka edycyjna). Dodatkowo serwer umożliwia przesłanie do klienta komunikatu tekstowego umieszczonego w osobnym oknie edycyjnym. Aplikacja umożliwia zamknięcie połączenia (wraz z wątkiem głównym serwera) po wciśnięciu odpowiedniego przycisku. Wówczas ustawiane jest odpowiednie zdarzenie, które odebrane w wątku serwera powoduje zamknięcie gniazda nasłuchu i zakończenie wątku. Ź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 rozpoczyna oczekiwanie na nadchodzące komunikaty tekstowe * w przypadku otrzymania komunikatu umieszcza go w pierwszym (wejściowym) oknie edycyjnym * w przypadku odebrania zdarzenia zamknięcia zamyka gniazda i kończy działanie wątku * Przycisk ''Send'' * w przypadku gdy istnieje aktywne połączenie wysyła do klienta tekst umieszczony w drugim (wyjściowym) polu edycyjnym ===== 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) **Synchronizacja wątków za pomocą zdarzeń** * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms682396%28v=vs.85%29.aspx|CreateEvent]] tworzy uchwyt do obiektu zdarzenia * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms686211%28v=vs.85%29.aspx|SetEvent]] ustawia obiekt zdarzenia w stanie sygnalizującym zajście zdarzenia * [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms685081%28v=vs.85%29.aspx|ResetEvent]] przywraca pierwotny stan zdarzenia * [[https://msdn.microsoft.com/en-us/library/ms687032%28v=vs.85%29.aspx|WaitForSingleObject]] **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 \\ <code c>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)); </code> * [[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