====== Winsocket: klient - serwer ======
===== Zadanie 1 - Komunikator tekstowy =====
Napisz program do komunikacj tekstowej dla dwóch użytkoników (czat) o architekturze klient-serwer. Zarówno klient jak i serwer posiadaja pole edycyjne w którym można wpisać komunikat i wysłać go wciskając odpowiedni klawisz. Przesyłane informacje oraz ewentualne komunikaty są umieszczane w osobnej kontrolce. Obsługę zdarzeń związanych z siecią zrealizuj w sposób asynchroniczny wykorzystując mechanizm komunikatów okna oraz funkcję [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms741540%28v=vs.85%29.aspx|WSAAsyncSelect]]
==== Serwer =====
Aplikacja uruchamia nasłuch i czeka na połaczenie z klientem. Domyślnie połączenie realizowane jest na porcie 1234 (rozważ dodanie możliwości zmiany portu). Serwer obsługuje komunikaty FD_ACCEPT (zaakceptowanie połączenia), FD_READ (nadchodząca wiadomość), FD_CLOSE (zamknięcie połączenia).\\
**Przydatne funkcje:**
* 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/ms741540%28v=vs.85%29.aspx|WSAAsyncSelect]] i makro ''WSAGETSELECTEVENT'' potrzebne do uruchomienia i obsługi zdarzeń sieciowych za pomocą komunikatów okna
* [[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
==== Klient ====
Aplikacja łączy się z serwerem. Domyślnie połaczenie realizowane jest pod adresem ''localhost'' na porcie 1234. Dodaj możliwość zdefiniowania w odobnym oknie dialogowym ustawień połącznia. Klient obsługuje komunikaty FD_READ (nadchodząca wiadomość), FD_CLOSE (zamknięcie połączenia).\\
**Przydatne funkcje:**
* [[https://msdn.microsoft.com/en-us/library/windows/desktop/ms737625%28v=vs.85%29.aspx|connect()]] ustanawia połączenie poprzez gniazdo
===== Inne przydatne funkcje =====
* Dodawnanie tekstu do kontrolki edycyjnej \\
TCHAR *buffer = TEXT("append this!");
int index = GetWindowTextLength (hEdit);
SetFocus (hEdit);
SendMessageA(hEdit, EM_SETSEL, (WPARAM)index, (LPARAM)index);
SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)buffer);
* operacje na łańcuchach znakowych:
* ''_tcslen()'' długość napisu
* ''_tcsncat_s'' doklejanie jednego napisu na końcu drugiego
===== Zadanie 2 - Komunikator tekstowy - jedna aplikacja =====
Wykonaj zadanie 1 lecz zamiast tworzyć osobne aplikacje dla klienta i serwera stwórz program, który może działać zarówno jako klient jak i jako serwer. Domyślnie aplikacja uruchama się w trybie serwera nasłuchując przychodzących połączeń na podanym przez użytkownika porcie. W przypadku połączenia aplikacja pyta o pozwolenie na połączenie z wybranym zdalnym klientem. Aplikacja daje też możliwość połacznia ze zdalnym serwerem.
===== Zadanie 2 - Komunikator tekstowy wielowątkowy =====
Napisz komunikator tekstowy zgodnie z zadaniem 1 lub 2 bez używania zdarzeń sieciowych i funkcji ''WSAAsyncSelect''. Asynchroniczną wymianę informacji zrealizuj za pomocą wątków.