Aplikacje sieciowe i wielowątkowe

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 serwer.cpp
  • przykładowa aplikacja kliencka, którą można wykorzystać do testów 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

Obsługa wątków:

Synchronizacja wątków za pomocą zdarzeń

Komunikacja sieciowa:

  • plik nagłówkowy winsock2.h i biblioteka WS2_32.lib
  • WSAStartup, WSACleanup()
    inicjalizacja WinSocket
  • socket, closesocket(), tworzenie gniazda
  • 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));
  • inet_addr zamienia adres IP z postaci łańcucha znakowego do postaci liczby całkoiwtej
  • htons i htonl transfrormacja liczby short/long wymagana przy definiowaniu portu w protokole AF_INET i AF_INET6
  • listen() ustawia gniazdo w stanie nasłuchu
  • accept() ustanawia połaczenie, zwraca gniazdo łączące z klientem, pozwala na przesyłanie danych za pomocą send() i recv()
  • send() wysyła dane przez gniazdo
  • recv() odbiera dane z połacznoego gniazda