Chciałbym przedstawić zagadnienie związane z tworzeniem aplikacji w Visual C# wykorzystującej przestrzeń nazw System.Net. Przedstawiony przykład zobrazuje tworzenie serwera oraz klienta. Klasy przestrzeni nazw System.Net wykorzystywane są do obsługi wielu protokołów sieciowych np. TCP/IP.
Do wykonania aplikacji serwera zostały wykorzystane następujące klasy:
• IPAddress – reprezentacja adresu IP,
• IPEndPoint – punkt końcowy sieci IP – czyli adres IP wraz z portem,
Powyższe klasy służą do reprezentacji adresu IP, można również spotkać się z klasą DNS która służy do „tłumaczenia” nazw systemu DNS na adres IP. Może trochę niezrozumiałe ale adresy IP są trudne do zapamiętania, dlatego wprowadzono nazwy DNS - np.
http://www.atnel.pl. Wykorzystując klasę DNS możemy z „www.atnel.pl” wyłuskać adres IP.
Poniższe dwie klasy należą do przestrzeni nazw System.Net.Socket. Klasy tej przestrzeni umożliwiają przesyłanie danych pomiędzy dwoma programami.
• TcpListener – reprezentacja strony serwera
• TcpClient – reprezentacja strony klienta
Klasa NetworkStram wykorzystywana jest do odczytywania i zapisywania danych.
• NetworkStream – klasa przeznaczona do odczytu/zapisu danych
1) Serwer
Aplikacja serwera zostanie wykonana w oparciu o ConsoleAplication. Dlatego w pierwszej kolejności należy stworzyć aplikację konsolową. Do stworzonego projektu dodajemy dwie przestrzenie nazw: System.Net oraz System.Net.Socket.
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Następnie należy zdefiniować adres IP serwera, dlatego do życia powołujemy obiekt klasy IPAddress do którego przekazujemy adres IP.
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Obiekt tej klasy najprościej utworzyć z wykorzystaniem metody Parse do której można przekazać adres IP w postaci “string”.
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Tworzymy dwa obiekty TcpListener oraz TcpClient, których przeznaczenie zostało omówione w wstępie. Metoda Start() przeznaczona jest do rozpoczęcia nasłuchu na wcześniej zdefiniowanym adresie IP oraz porcie – oczekujemy na żądanie klienta. Metoda AcceptTcpClient() oczekuje aż połączy się klient.
Następnie odbieramy strumień danych wysłany przez klienta. Wykorzystujemy do tego klasę NetworkStram.
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Do stowrzonego obiektu klasy NetworkStram przekazujemy strumień pochodzący z obiektu clientSocket. W najprostrzej postaci tworzymy nieskończoną pętle while służąca do ciągłego odbierania danych ( alternatywnym rozwiązaniem jest wykorzystanie wątku).
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Po odebraniu danych należy “posprzątać” – czyli zamknąć wszystkie otwarte połączenia.
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
2) Klient
Klient wysyłający dane zostanie wykonany w oparciu o WindowsFormApplication. Podobnie jak w aplikacji serwerowej zostanie stworzony obiekt TcpClient ( jego rola została opisana w wstępie) Aplikacja okienkowa wykorzystuje dwa komponenty textbox oraz dwa buton.
Jeden textbox jest ustawiony na multiline. Dokonać tego możemy poprzez properties -> multiline -> true.
W pierwszej kolejności stworzymy metodę pozwalającą dodawać tekst do komponentu textbox (dużego).
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Metoda pozwala na wyświetlenie poprzednio dodanego tekstu oraz dodanie w nowej linii przekazanego „strigna”. Enviroment.NewLine jest wykorzysytwany do przejścia do następnego wiersza, alternatywnie można wykorzystać zapis „/n”.
Tworzymy jako globalny obiekt klasy TcpClient który podobnie jak w przypadku serwera wykorzystujemy do reprezentacji strony klienta.
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Dwukrotnie klikając w buton znajdujący się na formie ( jeżeli jesteśmy w oknie wprowadzania kodu klikamy F7, aby przejść do formy graficznej). Pod przycisk wprowadzamy następujący fragment kodu:
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
W pierwszej linii kodu do metody msg przekazujemy tekst przeznaczony do wyświetlenia w textboxie. Następny fragment kodu opatrzony jest instrukcją try, pozwala to na przechwycenie błędów występujących podczas próby połączenia się. Instrukcja catch przechwytuje wyjątki i odpowiednio je „interpretuje”. W podanym fragmencie kodu podczas wystąpienia wyjątku następuje jego wyświetlenie w textboxie. Przechwytywane są wszystkie wyjątki SocketException(związane z komunikacją), ponieważ nie zalecane jest przechwytywanie wszystkich wyjątków – czyli robienie takiego czegoś:
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Każdy wyjątek przewidziany przez programistę powinien być obsłużony, lecz nie zaleca się przechwytywania wyjątków System.Exception ( zalecenia Microsoft).
Połączenie odbywa się podobnie jak w przypadku serwera do metody Connect przekazujemy dwa parametry- adres IP oraz port. W naszym wypadku przekazujemy „localhost” lub adres 127.0.0.1. W podanym wyżej fragmencie kodu do życia został powołany obiekt klasy NetworkStream pozwalający na obsługę strumieni pochodzących z klasy TcpClient.
W pierwszej kolejności do serwera zostaje wysłany nazwa lokalnego hosta (przedstawienie się), dokonujemy tego w sposób przedstawiony w poniższym kodzie:
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Metoda GetHostName() zwraca jako string nazwę lokalnego komputera. Do nazwy zostaje dodany znak dolata „$” w celu wykrycia przez serwer koniec linii ( można też to zrobić w inny sposób, ja zrobiłem tak). String złożony z nazwy komputera oraz znakiem dolara jest przekazany do metody zamieniającej znaki ASCII na byte. Otrzymana w ten sposób tablica byte zostaje przekazana do wcześniej utworzonego strumienia na którym jest wywołana metoda Write w której jako parametry podajemy kolejno dane do wysłania, offset, oraz rozmiar tablicy ( C# umożliwia odczytanie tej długości przy pomocy metody Length).
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Pod drugi przycisk wprowadzamy opcje odbierania i wysyłania danych. Oparte jest to na strumieniach tak jak już szybciej pokazywałem, dlatego nie będę tego fragmentu kodu omawiał.
język csharp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Powodzenia przy tworzeniu swoich aplikacji wykorzystujących komunikację TCP/IP. Uwagi i sugestie mile widziane.