Internet - teenused, protokollid, pordid...
Sageli on Interneti teenused korraldatud nn. klient/server mudelit aluseks võttes. Teenuse saamiseks esitab klient tellimuse, millele vastuseks server võib algatada protsessi tellimuse täitmiseks. Põhimõtteliselt võib sama tellimuse täitmisse olla kaasatud mitu serverit. Kommunikatsiooni aktiivne pool on klient (vahel kasutatakse seda määratlust mõiste "klient" defineerimiseks).Tuleb teha vahet teenusel (näiteks failide ülekanne: FTP - file transfer protocol), seda teenust realiseerival tarkvaral (ftp-server ühel pool ning ftp-klient teisel pool) ja protokollil, mis teeb võimalikuks nende programmide vahelise suhtlemise (ftp-protokoll). Sõltuvalt kontekstist tuleb siis selgeks teha, millest on jutt, sest üldnimi tähistab neid kõiki.
Server-programm (spetsiifilisemas sõnavaras deemon) on pidevalt valvel ja kuulab, kas tema poole soovib pöörduda mõni klient, olles üldjuhul võimeline teenindama kliente paralleelselt (Java seisukohalt vaadates - server algatab uue kliendi jaoks uue lõime).
Interneti klient/server programmid suhtlevad nn. portide kaudu.
Vastavalt protokolli tüübile jagatakse porte TCP- ja UDP-portideks. Näiteks paljudes Unixi versioonides on üks Interneti deemon - inetd, mis kuulab TCP-porte ja organiseerib konkreetsete serverprogrammide täitmist. TCP - transmission control protocol - on Interneti protokoll (mis OSI mudeli järgi kuulub transpordikihti), mis tagab pideva ühenduse kahe võrgusõlme vahel.Iga teenusega on seotud kindel protokoll infovahetuseks kliendi ja serveri vahel. Konkreetsed masinad, millel klient ja server töötavad, võivad olla väga erinevad - see ei tohiks olla oluline (vahel on klient ja server ka samas masinas).
Protokollideks on näiteks:
telnet - kaugterminaaliga suhtlemise protokoll
ftp, ftp-data - failide ülekande protokollid (file transfer protocol)
smtp - kirjavahetuse protokoll (simple mail transfer protocol)
nntp - võrguuudiste edastamise protokoll (network news transfer protocol)
http - hüperteksti edastamise protokoll (hypertext transfer protocol)
finger - protokoll lühiinformatsiooni edastamiseks kasutaja või süsteemi kohta
rpc - hajussüsteemide tööks vajalik kaugprotseduuri väljakutse protokoll (remote procedure call)
snmp - võrgu teeninduseks vajalik protokoll (simple network management protocol)
ntp - ajateenistusprotokoll (network time protocol)
nfs - protokoll hajusa välismäluga töötamiseks (network file system)
....Samas arvutis võib korraga olla käimas mitmeid rakendusi, nii kliente kui ka servereid. Et aru saada, milline pakett millise rakenduse juurde kuulub, tuleb korraldada nende sorteerimine nn. portide kaupa. Porte iseloomustatakse numbrite abil (täisarv vahemikus 0 kuni 65535), seejuures numbrid 0 kuni 1023 on reserveeritud kindlate rakenduste jaoks (ingl.k. well known ports)Teenusega serveri poolt on seotud konkreetne pordi number (näiteks e-post - 25, telnet - 23 jne.), kuid kliendipoolne pordi number määratakse dünaamiliselt, et tagada ühenduse ühene identifitseerimine. Näiteks saab samade arvutite vahel korraga saata mitut kirja. Selleks, et erinevatesse kirjadesse kuuluvad paketid segi ei läheks, peab iga kirja jaoks olema eraldi ühendus, s.t. erinev komplekt pordinumbreid.
Kokkuvõttes iseloomustab iga seanssi 4 parameetrit: kummagi osapoole IP-aadress ning pordi number, mille kaudu suhtlemine toimub. Kasutajale on oluline teada just serveripoolseid (standardseid) pordinumbreid, et ühendust algatada juhtumil, kui kasutatakse mittetraditsioonilisi teenuseid. Pordinumber on mittekohustuslik osa URL (uniform resource locator) koosseisus.
Tehniliselt (protokolle aluseks võttes) võib eristada nn. UDP-porte (user datagram protocol) (näit. 69 - TFTP trivial ftp, 123 - NTP network time protocol, 161 - SNMP simple network management protocol, ....), mis tagavad kohalejõudmisgarantiideta kiire paketiedastuse ja TCP-porte (transmission control protocol) (näit. 20 - FTP-DATA, 21 - FTP, 23 - TELNET, 25 - SMTP, 79 - FINGER, 119 -NNTP ....), mis tagavad pideva ühenduse sõlmede vahel. TCP-portide ja UDP-portide numbrid ei ole omavahel mitte kuidagi seotud!
DNS - Domain Name Service on teenus IP-aadresside seostamiseks nimedega. Iga nimega ei pruugi olla seotud IP aadressi, sest näiteks e-post liigub ka muudes (mitte-TCP/IP) võrkudes. Samuti ei pruugi igale IP-aadressi omavale võrguseadmele panna nime.
Nimed Internetis moodustavad loogilise hierarhia - üldisemad nimekomponendid paiknevad seejuures tagapool. Juurtasemel: .ee .fi .se .de .fr .uk .no jne. riikide kaupa; .com .edu .gov .mil .net .org tegevusala järgi (peamiselt USA).
Nimedoomen (näit. .ut.ee ) ühendab teatud hulka masinaid loogiliselt ning on üksuseks administreerimisel. Masinanimi on esimene komponent Internet-nimes (näit. romulus.cs.ut.ee).
Alati on soovitav kasutada täielikku Interneti-nime (eriti kirjade saatmisel).
IP aadress on seotud füüsilise võrguga ning selle jagunemisega alamvõrkudeks. IP aadressi teadmisel saab masina poole pöörduda nimeserveri vahenduseta (praktikas on hea teada oluliste masinate IP-aadresse, kindlasti enda masina oma). Masinanimi on lokaalse tähendusega ning tihedalt seotud operatsioonisüsteemiga. Tavaliselt saab ühes lokaalvõrgus olevate masinate Interneti-nime asemel kasutada masinanime (näit. rlogin brutus). Võib korraldada nii, et samas doomenis olevate masinate poole pöördumisel tohib doomeni nime osa ära jätta.
Nimeserver lubab nn. kanoonilise nime kõrvale luua ka sünonüüme (näit. ftp.ut.ee, archie.funet.fi). Heaks kombeks ongi kasutada teenuste identifitseerimiseks teenuse nime esimese nimekomponendina. Huvitab ju kasutajat ennekõike juurdepääs teenusele (näit. news.ut.ee), mitte antud hetkel seda teenust pakkuva masina kanooniline nimi (näit. kadri.ut.ee).
Nimeserveris on kirjas IP aadress, masina kanooniline nimi, andmed riistvara ja OS kohta, andmed kirjade haldamise kohta jne. Tuleks teada oma lähimat nimeserverit ja lisaks mõnda
tagavaraserverit. Internetiühenduse konfigureerimisel ongi tüüpiliselt tarvis teada oma masina IP-aadressi, võrgumaski, nimeserverit ja marsruuti, kuhu väljuvad paketid suunata.
NAT - Network Address Translation, tulemüürid.
Paketi java.net mõned vahendid
Internet URL tasemel
InetAddress
URL
URLConnectionTCP pistikliides
Socket
ServerSocket
SocketException ( <- IOException <- Exception )UDP pistikliides
DatagramPacket
DatagramSocketÜhenduseta protokollid - UDP, datagrammide saatmine
Näide - server
/*
* Fail Dserver.java
*/
import java.net.*;
import java.io.*;
import java.util.Date;
public class Dserver {
public static void main (String [] parameetrid) {
int pordinumber; // UDP-pordi number
if (parameetrid.length == 0)
pordinumber = 5678;
else pordinumber = Integer.parseInt (parameetrid [0]);
try {
DatagramSocket dpistik = new DatagramSocket(pordinumber);
// analoog serverpistikuga -- istume ja kuulame
while (true) { // lopmatu tsu"kkel, ctrl-c abil va"lja
byte [] andmed = new byte [1024];
DatagramPacket pakett = new DatagramPacket
(andmed, andmed.length);
dpistik.receive (pakett);
String teade = new String
(pakett.getData(), 0, pakett.getLength());
InetAddress aadress = pakett.getAddress();
System.out.println ("\nSaabus " + aadress.toString() +
" " + new Date().toString() + ":\n" + teade);
}
}
catch (IOException e) {
System.out.println (e);
}
} // main lopp
} // Dserver loppKlient (rakend)
/**
* Fail Dklient.java
*/
import java.net.*;
import java.io.*;
import java.applet.Applet;
import java.util.Date;
import java.awt.Graphics;
public class Dklient extends Applet { // kliendipool on rakend
InetAddress aadress; // serveri aadress
int pordinumber; // suhtlemiseks kasutatav UDP-port
public void init() { // Applet-klassi meetodi u"lekatmine
try {
aadress=InetAddress.getByName(getCodeBase().getHost());
if (getParameter ("port") == null)
pordinumber = 5678; // suvaliselt valitud va"a"rtus
else pordinumber =Integer.parseInt(getParameter("port"));
// pordinumber tuleb veebilehelt parameetrina
}
catch (UnknownHostException e) {
// to"o"delda
}
}
void saada (String teade) {
try {
byte [] andmed = teade.getBytes();
DatagramPacket pakett = new DatagramPacket
(andmed, andmed.length, aadress, pordinumber);
DatagramSocket dpistik = new DatagramSocket();
dpistik.send (pakett);
dpistik.close();
}
catch (IOException e) {
// to"o"delda
}
}
public void start() { // Applet-klassi meetodi u"lekatmine
String s = " " + new Date().toString() + " " +
System.getProperty ("os.name") + " " +
System.getProperty ("os.version") + " " +
System.getProperty ("os.arch") + "\n " +
System.getProperty ("java.vendor");
saada (s);
}
public void stop() { // Applet-klassi meetodi u"lekatmine
String s = " " + new Date().toString() + " lahkus lehelt";
saada (s);
}
public void paint (Graphics ekraan) { // Applet-klassi meetod
ekraan.drawString ("Spioon" , 50, 25);
}
} // Dklient loppKliendipoolne veebileht
<!-- Fail Dklient.html -->
<!-- autor: J.Poial -->
<HTML>
<HEAD>
<TITLE>Klient</TITLE>
</HEAD>
<BODY>
<APPLET code="Dklient.class" width=300 height=100>
<param name="port" value="5678">
</APPLET>
</BODY>
</HTML>Ühendusega protokollid - TCP, voogude töötlemine
Pistikliidesega klient (tellimus standardsisendist)
/**
* Fail DirKlient.java
*/
import java.net.*;
import java.io.*;
public class DirKlient {
public static void main(String[] parameetrid) {
String serveriNimi = "localhost"; // server
int pordinumber = 7654; // TCP-port
if (parameetrid.length == 1)
pordinumber = Integer.parseInt (parameetrid [0]);
else if (parameetrid.length > 1) {
serveriNimi = parameetrid [0];
pordinumber = Integer.parseInt (parameetrid [1]);
}
try {
Socket pistik = new Socket (serveriNimi, pordinumber);
InputStream sisse = pistik.getInputStream();
BufferedReader svoog = new BufferedReader
(new InputStreamReader (sisse));
OutputStream valja = pistik.getOutputStream();
PrintWriter vvoog = new PrintWriter
(new OutputStreamWriter (valja), true);
BufferedReader klav = new BufferedReader
(new InputStreamReader (System.in));
System.out.print ("Anna tellimus: ");
String tellimus = klav.readLine();
System.out.println ("Saadan tellimuse: host = "
+ pistik.getInetAddress() + " , port = "
+ pistik.getPort() + "\n localhost = "
+ pistik.getLocalAddress() + " , localport = "
+ pistik.getLocalPort());
vvoog.println (tellimus);
System.out.println ("Sain vastuseks:");
String rida;
while ((rida = svoog.readLine()) != null)
System.out.println (rida);
pistik.close();
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
} // main lopp
} // DirKlient loppServer (vastuseks kataloogi sisu)
/**
* Fail DirServer.java
*/
import java.io.*;
import java.net.*;
public class DirServer {
public static void main (String [] parameetrid) {
int pordinumber = 7654; // TCP-port
if (parameetrid.length > 0)
pordinumber = Integer.parseInt (parameetrid [0]);
try {
ServerSocket kuulaja = new ServerSocket (pordinumber);
while (true) {
new DirLoim (kuulaja.accept()); //argument on Socket
}
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
} // main lopp
} // DirServer lopp
class DirLoim extends Thread {
Socket pistik; // igal lo~imel oma pistik
DirLoim (Socket p) {
pistik = p;
setPriority (NORM_PRIORITY - 1);
// kuulamine on pisut tähtsam kui töötlemine
start();
}
public void run() { // katame üle
try {
InputStream sisse = pistik.getInputStream();
BufferedReader svoog = new BufferedReader
(new InputStreamReader (sisse));
OutputStream valja = pistik.getOutputStream();
PrintWriter vvoog = new PrintWriter
(new OutputStreamWriter (valja), true);
String rida;
if ((rida = svoog.readLine()) != null) {
System.out.println ("Pordi " + pistik.getPort()
+ " kaudu saabus tellimus:\n" + rida);
String vastus = annaVastus (rida);
vvoog.println (vastus);
System.out.println ("Pordi " + pistik.getPort()
+ " kaudu saadeti vastus:\n" + vastus);
}
pistik.close();
}
catch (IOException e) {
System.out.println ("S/V viga: " + e);
}
} // run lopp
static String annaVastus (String tellimus) {
File f = new File (tellimus);
if (!f.exists() || !f.canRead())
return ("Ei saanud aru: " + tellimus);
if (f.isDirectory()) {
String [] nimekiri = f.list();
StringBuffer vastus = new StringBuffer();
for (int i=0; i<nimekiri.length; i++) {
vastus.append (nimekiri [i]);
vastus.append (" ");
}
return vastus.toString();
} else if (f.isFile()) {
return "On niisugune fail";
} else return "Segane lugu" ;
} // annaVastus lopp
} // DirLoim loppURL - uniform resource locator
Näide lugemisest (fragment)
String s = "http://www.cs.ut.ee/";
URL viide = new URL (s);
System.out.println ("Protocol = " + viide.getProtocol());
System.out.println ("Host = " + viide.getHost());
System.out.println ("Filename = " + viide.getFile());
System.out.println ("Port = " + viide.getPort());
System.out.println ("Ref = " + viide.getRef());
System.out.println ("Sisu:");
BufferedReader sisend = new BufferedReader
(new InputStreamReader (viide.openStream()));
String rida;
while ((rida = sisend.readLine()) != null)
System.out.println (rida);
sisend.close();
Pakett javax.net.ssl - Secure Socket Layer
Annab raamid TCP-pistikliidese turvamiseks SSL-protokolli abil.
Jaanus Pöial, 2004