Java hálózati alkalmazások Socket, URL
Protokollok java.net: socket, URL (Uniform Resource Locators) Protokoll: számítógépek közötti kommunikáció szabályai Internet TCP/IP (Transport Control Protocol/Internet Protocol) IETF (Internet Engineering Task Force) standardok Java: a TCP/IP szint feletti protokollok implementációja HTTP (HyperText Transfer Protocol) és FTP (File Transfer Protocol) használata Predefiniált osztályok és interfészek alkalmazása (nem szükséges az implementációs részletek és adatstruktúrák ismerete)
Kliens-szerver modell Szerver: a hálózaton keresztül érkező kliens kérések teljesítése Web a kliensek által kért dokumentumok biztosítása (HTTP/HTTPS) E-mail - SMTP (Simple Mail Transfer Protocol), IMAP4 (Internet Mail Access Protocol), POP3 (Post Office Protocol) NFS (Network File System) FTP (File Transfer Protocol) DNS (Domain Name Service) NIS (Network Information Service) TELNET, RLOGIN, SSH (Secure Shell), XDMCP (X Display Manager Control Protocol) (belépés távoli rendszerekre) Stb. Kliens: használja a szerver által biztosított szolgáltatásokat. Ehhez ismernie kell a szerver címét, a kommunikációra használt portot és protkollt
Port és socket Port: kapu a kliensek fogadásához Egy címen több különböző szolgáltatás is futhat, különböző portokon A port száma: 1-65535, az IETF szerint 1-1024 foglalt (80 HTTP, 21 FTP, 23 TELNET stb.) Socket: absztrakt kommunikációs csomópont (a fogalmat a BSD UNIX vezette be) Alacsonyszintű interfész hálózati kommunikációhoz Azonos vagy a hálózaton belül különböző számítógépeken futó processzek közötti kommunikáció Java: három socket típus, adatfolyamokat (stream) használnak az üzenetek küldéséhez/fogadásához Socket - TCP DatagramSocket UDP (nem kapcsolat orientált) MulticastSocket a DatagramSocket változata, amely több receptorhoz küldhet adatokat
Socket és ServerSocket Kapcsolat orientált kommunikáció, TCP Két rész: kliens és szever a kliens kéréseket küld, a szerver válaszol A kliens a kéréshez létrehoz egy Socket-et, a szerver készen áll a kérések fogadására (ServerSocket), a kérés fogadásakor létrehoz egy szerver oldali Socket-et, és ezen keresztül biztosítja a kért szolgáltatást. A kliensnek ismernie kell a szerver nevét (az IP cím lekéréséhez) és a használt port-ot.
Párhuzamos/szekvenciális szerver Általában párhuzamos (parallel/concurent) szervereket alkalmazunk: minden kliens részére egy külön végrehajtási szálat hozunk létre A szerver által végrehajtott tipikus műveletek: 1. A szerver kioszt egy kommunikációs port-ot (ezt ismerik a kliensek) 2. while (vannak kliensek a port-nál) { A kapcsolat létrehozása (Socket létrehozása) A kliens kiszolgálása (bemeneti/kimeneti adatfolyam) A kapcsolat felbontása (Socket felszabadítása) A kliens által végrehajtott műveletek: Kommunikációs port kiválasztása Kapcsolódás a szerverhez Socket létrehozása, adatok küldése és fogadása (adatfolyamok)
A Socket osztály Konstruktorok: Socket(InetAddress address, int port) Socket(InetAddress address, int port, InetAddress localaddr, int localport) - (a kliens cím/port megadásával) Socket(String host, int port) Socket(String host, int port, InetAddress localaddr, int localport) Fontosabb metódusok: void close() InetAddress getinetaddress() InputStream getinputstream() InetAddress getlocaladdress() int getlocalport() OutputStream getoutputstream() int getport()
A ServerSocket osztály Konstruktorok: ServerSocket(int port) ServerSocket(int port, int backlog) (a várakozási sor hosszának megadásával) Fontosabb metódusok: void close() Socket accept() InetAddress getinetaddress() int getlocalport()
Példa A kliens elküld egy karaktersort, a szerver visszaküldi nagybetűkbe konvertálva
Server.java //Source file: c:\clientserver\serverpackage\server.java package ServerPackage; public class Server { public static void main(string[] args) { int port; if( args.length <1 ) { System.out.println( "Usage Server <portnumber>"); System.exit( 1 ); try{ port = Integer.parseInt( args[ 0 ] ); catch( NumberFormatException e ) { port = 1024; try{ java.net.serversocket ss = new java.net.serversocket( port ); while( true ) ( new ClientHandle( ss.accept() )).start(); catch( java.io.ioexception e ) { System.out.println( "Server error ");
ClientHandle.java //Source file: c:\clientserver\serverpackage\clienthandle.java package ServerPackage; import java.net.socket; import java.net.socketexception; Import java.io.*; public class ClientHandle extends Thread { Socket client; public ClientHandle(Socket client) throws SocketException { this.client = client; public void run() { try{ InputStream in = client.getinputstream(); OutputStream out = client.getoutputstream(); BufferedReader myin = new BufferedReader(new InputStreamReader( in)); PrintWriter myout = new PrintWriter( new OutputStreamWriter( out )); String request = myin.readline(); System.out.println( "Request: "+request); myout.println( request.touppercase()); myout.flush(); myin.close(); myout.close(); client.close(); catch( java.io.ioexception e ) { System.out.println("I/O error "+e );
Client.java //Source file: c:\rose\clientserver\clientpackage\client.java package ClientPackage; public class Client { private String hostname; private int hostport; private String message; public Client(String hostname, int hostport, String message) { this.hostname = hostname; this.hostport = hostport; this.message = message; doit(); public void doit() { try{ java.net.socket s = new java.net.socket( hostname, hostport ); java.io.bufferedreader in = new java.io.bufferedreader( new java.io.inputstreamreader(s.getinputstream())); java.io.printwriter out = new java.io.printwriter( s.getoutputstream() ); out.println( message ); out.flush(); System.out.println("Answer from the server: "+in.readline() ); s.close(); catch( java.io.ioexception e ) { System.out.println( "I/O error "+e );
Client.java public static void main(string[] args) { String hostname, message; int hostport; if( args.length < 3 ) { System.out.println("Usage Client <hostname> <hostport> <message>"); System.exit( 1 ); hostname = args[ 0 ]; message = args[ 2 ]; try{ hostport =Integer.parseInt( args[ 1 ] ); catch( NumberFormatException e ) { hostport = 1024; Client c = new Client( hostname, hostport, message ); Más példa: egyszerű HTTP szerver
User Datagram Protocol (UDP) Nem kapcsolat orientált Példa: postai szolgálat, levél küldése (boríték datagram) Nem biztos kapcsolat: nincs visszajelzés az érkezéskor, a továbbítási útvonal nem ismert a küldés pillanatában (így ha többet küldünk egy címzetthez, a megérkezés sorrendje is bizonytalan) Gyors, és alkalmazható olyan esetekben, amikor nem túl nagy Gyors, és alkalmazható olyan esetekben, amikor nem túl nagy probléma egy-két csomag elvesztése (pl. DNS)
A DatagramPacket osztály Konstruktorok: DatagramPacket(byte[] buf, int length) DatagramPacket(byte[] buf, int length, InetAddress address, int port) DatagramPacket(byte[] buf, int offset, int length) DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) Fontosabb metódusok: InetAddress getaddress() byte[] getdata() int getlength() int getoffset() int getport() void setaddress(inetaddress iaddr) void setdata(byte[] buf) void setdata(byte[] buf, int offset, int length) void setlength(int length) void setport(int iport)
A DatagramSocket osztály Konstruktorok: DatagramSocket() (egy szabad port-ot rendel hozzá) DatagramSocket(int port) DatagramSocket(int port, InetAddress laddr) Fontosabb metódusok: void close() void connect(inetaddress address, int port) void disconnect() InetAddrress getinetaddress() InetAddress getlocaladdress() int getlocalport() int getport() void receive(datagrampacket p) void send(datagrampacket p)
Példa Egy applet értesíti a szervert minden elindításakor (felhasználható pl. weboldal látogatottságának mérésére)
MessageApplet.java //Source file: c:\clientpackage\messageapplet.java package ClientPackage; public class MessageApplet extends java.applet.applet { private String myhost; private int myport; public void init() { myhost = getcodebase().gethost(); myport = Integer.parseInt( getparameter("port")); public void sendmessage(string message) { try{ byte data[] =message.getbytes(); java.net.inetaddress addr = java.net.inetaddress.getbyname( myhost ); java.net.datagrampacket packet = new java.net.datagrampacket( data, data.length, addr, myport ); java.net.datagramsocket ds = new java.net.datagramsocket(); ds.send( packet ); ds.close(); catch( java.io.ioexception e ){ System.out.println(e ); public void start() { sendmessage("pagina incarcata");
A HTML fájl és a AppletServer.java A HTML fájl tartalma: <applet HEIGHT=10 WIDTH=10 CODE=MessageApplet.class> <param NAME="PORT" VALUE="1234"></applet> Az AppletServer: //Source file: c:\serverpackage\appletserver.java package ServerPackage; public class AppletServer { public static void main(string[] args) { try { java.net.datagramsocket s=new java.net.datagramsocket(integer.parseint(args[0])); while( true ){ //a szerver felkészül egy csomag fogadására byte data[] = new byte[1024]; java.net.datagrampacket packet = new java.net.datagrampacket( data,1024); //a szerver várja a csomagot s.receive( packet ); //kiveszi a csomagból az adatokat és kiírja a standard kimenetre String message = new String( packet.getdata()); System.out.println("Hostname: "+ packet.getaddress().gethostname()+" "+message); catch( java.io.ioexception e ){
Uniform Resource Locator (URL) Egy objektum Interneten keresztüli beazonosítása Három részből áll: protocol://hostname/objektum_neve vagy protocol://hostname:port/objektum_neve Protocol: http, ftp, stb. Hostname: az objektumot tároló számítógép neve (vagy IP címe) Port: csak akkor kell megadni, ha nem standard objektum:_neve: az objetum neve és elérési útja URL konstruktorok Java-ban: URL(String spec) URL(String protocol, String host, int port, String file) URL(String protocol, String host, String file) MalformedURLException t adnak, ha valami hiányzik a specifikációból (az objektum létezése nem ellenőrzött a példányosításkor, a kivétel akkor lép fel, ha hibás paraméterátadás történt).
URL alkalmazása URL példányosítása: try{ URL url = new URL("http","www.cid.com.ro",3128, "index.html"); System.out.println( url.tostring()); catch( MalformedException e ){ //a kivétel kezelése Alkalmazás applettek esetében try{ URL url = new URL("http", getdocumentbase(), "index.html"); System.out.println( url.tostring()); catch( MalformedException e ){ //a kivétel kezelése Az adatok lekérése: az URL-nek megfelelő adatfolyam lekérése (openstream()) try{ URL url = new URL("http://www.cid.com.ro/index.html"); BufferedReader bin = new BufferedReader( new InputStreamReader(url.openStream())); String line; while( ( line = bin.readline())!= null ) System.out.println( line ); catch (Exception e ){