Számítógép-hálózatok: Labor 3
UDP idő szerver
A gyakorlat célja: UDP protokollal kapcsolatos ismeretek elmélyítése. Egy UPP protokollt használó időszerver megvalósítása Elméleti bevezető: UDP Protokoll föbb tulajdonságai: Az Internet összeköttetés nélküli szállítási protokollja az UDP. Létezik megbízhatatlan és nyugtázott formája is, általában a nyugtázott formát használják. Csomagformátuma az 1 ábrán található.
1. ábra: Az UDP csomag szerkezete Összekötetés nélküli kommunikációs protokoll azt jelenti, hogy üzenet váltás elött nincs szükség kommunikációs csatorna kiépítésére. Legjobban a levelezésre hasonlít, ahol elégséges ismerni a cél pontos címét. Az üzenetet betehetjük egy “borítékba”, amelyen megadjuk a címzett elérhetőségét. Nem megbízható. Alapértelmezés szerint az UDP protokoll nem rendelkezik arról, hogy a fogadó fél értesítést küldjön az küldemény sikeres megérkezéséről. Ezért nem tudjuk biztosan hogy a csomag megérkezett vagy sem. Vannak viszont olyan megvalósítások, ahol nyugtát küldenek minden egyes megkapott UDP csomagról. Van maximális mérete. Egyszeri küldéssel nem tudunk bármekkora méretű adatot elküldeni. Ezt egyrészt meghatározza az UDP mező hossza (16 bit) valamint az IP csomagok hossza. Az egy csomagban elküldött üzenet egy csomagban érkezik meg. Abban az esetben ha a csomag nem haladja meg az UDP csomag maximális méretét ha megérkezik akkor egyszerre kerül kézbesítésre. UDP Szerver Az UDP szervernek a szerkezete nagyon hasonló az UPD klienséhez. Az egyetlen eltérést a címzett státusz képezi.
Számítógép-hálózatok: Labor 3 Egy UDP vagy TCP alkalmazás megcímzése négy összetevővel rendelkezik:
MAC cím: fizikai szinten címzi meg a hálózati intefészt. Programozási szemponból nem érint.
IP cím: hálózati szinten címzi meg a hélózati interfészt (kártyát).
Protokoll típusa. A hálózati csomag jelen esetben az IP csomag fejrészében egy mezőben van meghatározzva hogy milyen tipusú csomagot szállít az adott csomag
Port: meghatározza, az alkalmazás kommunikációs csatornáját SOCKET végponttal. Szállítási réteg protokolljainak a fejrészében találjuk meg a portra vonatkozó mezőt.
A címzett státusz nem azt jelenti, hogy a kliens nem rendelkezi ugyanugy sajat címmel, mint a szerver, hanem azt hogy a szerver címét mindenki jól ismeri. Ez azt is jelenti, hogy a szerver bármikor újraindul az alkalmazás ugyanazzal a címmel kell rendelkezzen. A címzés egyedüli kérdéses összetevőjét, a port képezzi. Léteznek ugynevezet rövid életű portok, amelyeket az operációs rendszer automatikusan hozzárendel minden létrehozott végponthoz (SOCKET), minden induláskor változhat a port. A másik oldalon vannak az ugynevezett hosszúéletű portok, amelyet egy rendszerhívással lehet csak hozzárendelni az adott sockethez. Ez biztosítja, hogy minden újrainduláskor az alkalmazás ugyan azon a porton várja a beérkéző kéréseket. A hosszúéletű végpontok hozzárendelését a következő rndszerhívással lehet elvégezni: int bind( __in SOCKET s, __in const struct sockaddr *name, __in int namelen );
s [in] Egy szoket azonosító amelyhez még nem volt cím hozzárendelve. name [in] Sockethez hozzárendelt sockaddr cím struktura. namelen [in] name paraméter hossza, bájtban. A függvény viszatérítési értéke 0 ha sikeres, ellenben SOCKET_ERROR amelyet WSAGetLastError lehet lekérdezni. Leggyakoribb hiba az alkalmazásánál, amikor egy létrenem hozott sockethez probálok hozzárendelni egy címet, a második leggyakoribb hiba, amikor egy olyan sockethez probálok hozzárendelni egy címet, amelyhez már hozzárendeltem egyszer.
NETSTAT ezköz Jelenlegi TCP(UDP)/IP hálózati kapcsolatok protokoll statisztikákat jelenít meg
Számítógép-hálózatok: Labor 3
NETSTAT [-a] [-b] [-e] [-f] [-n] [-o] [-p proto] [-r] [-s] [-t] [interval] -a Megjeleníti az összes kapcsolatot és portokat amelyek bejövő kéréseket vár. -b Megjeleníti a kapcsolatokhoz tartozó alkalmazásokat. Nem működik ha nincsen elég joga a felhasználónak. -e Ethernet statisztikákat jelenít meg. Lehet az –s opcióval kombinálni. -f Megjeleníti az idegen címek Fully Qualified Domain Names (FQDN) -n Megjeleníti a cimeket és a portokat a numerikus formában. -o Megjeleníti az összes kapcsolat a tulajdonos folyamatjának az ID-ját. -p proto Megjeleníti azokat a kapcsolatokat amelyeket proto meghatároz; proto a kovetkező tipusú protokoll lehet: TCP, UDP, TCPv6, or UDPv6. -r Megjeleníti a forgalomírányitási táblát. -s Megjelenít a per-protocol statisztikát. Alpabol a közetkező statisztikákat jeleníti meg IP, IPv6, ICMP, ICMPv6, TCP, TCPv6, UDP, és UDPv6;
1. ábra UDP szerver kliens alkalmazások szerkezete
Számítógép-hálózatok: Labor 3 Feladat: 1. Írjatok egy UDP időszerver alkalmazást, amely minden egyes kérésre függetlenül a kérés tartalmától visszaküldi a pontos időt. Az alkalmazás szerkezetét lásd 1.ábrán. 2. Használva a Netstat ezközt kövesd figyelemmel a szerver és a kliens állapotait Példaprogram: #include <stdio.h> #include "winsock2.h" void main() { WSADATA wsaData; SOCKET SendSocket; sockaddr_in RecvAddr; int Port = 27015; char SendBuf[1024]; int BufLen = 1024; //--------------------------------------------// Initialize Winsock WSAStartup(MAKEWORD(2,2), &wsaData); //--------------------------------------------// Create a socket for sending data SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //--------------------------------------------// Set up the RecvAddr structure with the IP address of // the receiver (in this example case "123.456.789.1") // and the specified port number. RecvAddr.sin_family = AF_INET; RecvAddr.sin_port = htons(Port); RecvAddr.sin_addr.s_addr = inet_addr("123.456.789.1"); //---------------------// Bind the socket. if (bind( ListenSocket, (SOCKADDR*) & RecvAddr, sizeof(service)) == SOCKET_ERROR) { printf("bind() failed.\n"); closesocket(ListenSocket); return; } //----------------------------------------------// Call the recvfrom function to receive datagrams // on the bound socket. printf("Receiving datagrams...\n");
Számítógép-hálózatok: Labor 3 recvfrom(RecvSocket, RecvBuf, BufLen, 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize); // ido lekerese es elkuldese //--------------------------------------------// Send a datagram to the receiver printf("Sending a datagram to the receiver...\n"); sendto(SendSocket, SendBuf, BufLen, 0, (SOCKADDR *) &RecvAddr, sizeof(RecvAddr)); //--------------------------------------------// When the application is finished sending, close the socket. printf("Finished sending. Closing socket.\n"); closesocket(SendSocket); //--------------------------------------------// Clean up and quit. printf("Exiting.\n"); WSACleanup(); return; }
Kérdések: 1. A szervernél és a kliensnél milyen állapotokat sikerült azonósítani a netstat segítségével? 2. Megkorra a legnagyobb csomag, amit el tudsz küldeni egy UDP csomagban? 3. Mi történik ha egyidejüleg több kliens probálja lekérdezni a pontos időt. Könyvészet: [1]. A. Tanenbaum : Számítógéphálózatok. Bp., Panem Könyvkiadó, 2004. [2]. Buraga, S. - Ciobanu, G.: Atelier de programare în reţele de calculatoare. Iaşi, Polirom, 2001 [3]. http://www.iana.org/assignments/port-numbers [4]. http://msdn.microsoft.com/en-us/library/ms741416(VS.85).aspx