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ę 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 bibliotekaWS2_32.lib
- 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
- WSAAsyncSelect i makro
WSAGETSELECTEVENT
potrzebne do uruchomienia i obsługi zdarzeń sieciowych za pomocą komunikatów okna - 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()
irecv()
- send() wysyła dane przez gniazdo
- 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:
- 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.