====== 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.