Sieci komputerowe - Instrukcja do laboratorium nr 8
Autor: Robert Tomaszewski
Forma zaliczenia: zademonstrowanie działającego lub zaawansowanego programu na koniec zajęć i ewentualnie objaśnienie jego konstrukcji/działania (bez sprawozdania).
Bazując na materiałach opisujących WinSock'a udostępnionych przed zajęciami przez prowadzącego, na wiedzy zdobytej przy poprzednich ćwiczeniach oraz na wskazówkach umieszczonych na końcu tej instrukcji napisz program lub programy (w języku C) nadawcy (klienta) i odbiorcy (serwera) realizujące komunikację połączeniową (TCP).
Ogólny schemat działania programów:
- Inicjalizacja WinSock'a – WSAStartup (nadawca i odbiorca).
- Utworzenie gniazda – socket (nadawca i odbiorca).
- Nadawca – pobranie adresu IP, numeru portu serwera/odbiorcy oraz komunikatu do wysłania (wszystkie dane podaje użytkownik).
- Odbiorca – pobranie adresu IP i portu, na których ma nasłuchiwać serwer/odbiorca (dane podaje użytkownik).
- Nadawca i odbiorca – ustawienie pól struktury "sockaddr_in" pobranymi uprzednio danymi dla serwera/odbiorcy.
- Nazwanie gniazda – bind (odbiorca).
- Nawiązanie połączenia – connect (nadawca), nasłuch na gnieździe – listen (odbiorca).
- Wysyłka – send (nadawca).
- Akceptacja nawiązanego połączenia i automatyczne utworzenie nowego gniazda – accept (odbiorca).
- Odbiór i wyświetlenie odebranych danych – recv (odbiorca).
- Zamknięcie gniazda – closesocket (nadawca i odbiorca).
- Zwolnienie WinSock'a – WSACleanup (nadawca i odbiorca).
Wskazówki:
- Pamiętaj o włączeniu do programu nagłówka <winsock2.h> lub <winsock.h> oraz o dołączeniu dla potrzeb kompilacji biblioteki odpowiednio „ws2_32” lub „wsock32”.
- W strukturze „sockaddr_in” wypełniamy pola „sin_family”, „sin_port” i „sin_addr.s_addr” - trzeba pamiętać o konwersji numeru portu host-to-network po pobraniu liczby od użytkownika.
- Pobrany od użytkownika ciąg znaków opisujący adres IP (w postaci a.b.c.d) zamieniamy na liczbę funkcją „inet_addr”.
- Nadawca wysyła do odbiorcy dwie informacje (dwukrotne wywołanie „send”): wielkość informacji tekstowej („strlen” - z ewentualną konwersją „hton” przed wysyłką) i komunikat tekstowy.
- Odbiorca odbiera liczbę (z ewentualną konwersją odwrotną „ntoh”) oraz właściwy komunikat tekstowy (liczba informuje ile spośród odebranych znaków wyświetlić, aby uniknąć wyświetlenia „śmieci”) - dwukrotne wywołanie „recv”.
- Można nasłuchiwać na serwerze na wszelkich przypisanych mu adresach IP (adres.sin_addr.s.addr = htonl(INADDR_ANY);) a nie tylko na tym, który poda użytkownik (podanie nieprawidłowego adresu IP uniemożliwi nazwanie gniazda!).
- Jeżeli znamy nazwę serwera a nie znamy jego numeru IP (dane potrzebne klientowi) to możemy uzyskać IP serwera za pomocą funkcji „gethostbyname”.
- Funkcję „accept” wystarczy wywołać jednokrotnie (bez pętli, która jest demonstrowana w większości samouczków!), aby móc odebrać dwa razy komunikaty.
- Należy pamiętać, że odbiorca musi zamknąć dwa gniazda: utworzone funkcjami „socket” i „accept”.
- WAŻNE! Proszę zapoznać się z zawartością tej strony: http://tangentsoft.net/wskfaq/articles/effective-tcp.html – opisuje ona dokładniej specyfikę komunikacji strumieniowej.