Příklady Java Networking
Jednoduchý příklad spojově orientované komunikace
a metody třídy ServerSocket
Základní komponenty TCP komunikace
Příklad ukazuje základní kroky nutné při
vytváření TCP spojení. Nezbytné komponenty pro jakoukoliv komunikaci jsou:
- Komunikační protokol, např.
TCP
- Aplikační komunikační
protokol
- Program klienta
- Program serveru
Pro komunikace pomocí TCP jsou
nutné následující kroky:
- V programu serveru
vytvoření socketu ServerSocket a čekání na navázání spojení od klienta
v metodě ServerSocket.accept
- V programu klient vytvoření
socketu Socket s navázáním spojení se vzdáleným serverem.
- Po akceptování spojení je
vytvořen obousměrný komunikační kanál, použitelný pro komunikaci na aplikační
úrovni pomocí aplikačního protokolu.
V tomto případě je aplikační
komunikační protokol velmi jednoduchý.
- Klient pošle serveru
řetězec „Hello, Server“
- Server odpoví řetězcem „You
have connected to the Very Simple Server.“
- Poté klient i server
skončí.
Implementace
TCP klienta
Při implementaci TCP klienta musíme
provézt následující kroky:
- Vytvořit socket pro
komunikaci ze serverem na specifickém portu
- Vytvořit InputStream,
v našem případě typu BufferedReader pro příjem odpovědí od serveru
- Vytvořit OutputStream,
v našem případě typu PrintWriter pro posílání zpráv do serveru
- Zapsat do výstupního
streamu
- Číst ze vstupního streamu
- Před ukončením klienta
uzavřít InputStream, OutputStream a socket.
Jednoduchý program klienta (TcpClient.java)
může vypadat následovně.
Implementace
TCP serveru
Při implementaci TCP serveru musíme
provézt následující kroky:
- Vytvořit socket serveru (ServerSocket)
aby provedl listen a čekat na navázání spojení vyvoláním metody accept()
- Vytvořit InputStream,
v našem případě typu BufferedReader() pro příjem odpovědí od serveru
- Vytvořit OutputStream,
v našem případě typu PrintWriter() pro posílání zpráv do serveru
- Číst ze vstupního streamu
- Zapsat do výstupního
streamu
- Před ukončením serveru
uzavřít InputStream(), OutputStream() a socket.
Jednoduchý program serveru (TcpServer.java)
může vypadat následovně.
Metody třídy SocketServer
Třída ServerSocket implementuje socket TCP serveru. Obsahuje tři konstruktory,
které specifikují
Zadání internetové adresy dovoluje vytvářet
multihomed hosts, tj. počítače s přiřazenými dvěma a více internetovými
adresami, aby se omezil počet spojení na specifickém rozhraní.
ServerSocket obsahuje následující metody:
-
accept()
způsobí, že socket serveru bude naslouchat a čekat na příchod požadavku
navázání spojení. Po navázání spojení vrací metoda accept() instanci objektu
třídy Socket. Tento objekt je pak použit pro zajištění služby pro jednoho
klienta.
-
getInetAddress() vrací adresu hostitelského
počítače se kterým je socket spojen.
-
getLocalPort() vrací číslo portu, na kterém
server naslouchá.
-
toString() vrací adresu a číslo portu v podobě
vhodné k tisku.
-
getSoTimeout() a setSoTimeout() nastavuje hodnotu
parametru SO_TIMEOUT.
-
close() uzavírá socket serveru.
-
setSocketFactory(), statická metoda, je použita
pro změnu implicitního nastavení parametrů ServerSocket.
-
implAccept() je použita podtřídou ServerSocket
k přepsání metody accept().
Následující aplikace
ReverseServerApp.java je jednoduchý server,
který naslouchá na portu 1234. Po navázání spojení přečte jeden řádek textu,
změní pořadí znaků na opačné a takto upravenou řádku textu pošle zpět klientovi.
Spusťte nejprve
server
> java
ReverseServerApp
a pak klienta, např.
PortTalkApp
>java PortTalkApp localhost 1234
Metody třídy socket
Třída socket implementuje klientské sockety. Tyto sockety
jsou určeny pro aplikace, komunikující se servery pomocí protokolu TCP.
Metody třídy socket se používají pro přístup k I/O streamům
a parametrům spojení které jsou propojeny se spojeným socketem. Mezi tyto metody
patří:
- getInetAddress() a get|port(), které
dovolují získat IP adresu a port vzdáleného počítače.
- getLocalPort() vrací číslo lokálního portu,
spojeného se socketem
- getLocalAddress() vrací lokální IP adresu
počítače
- getInputStream() a getOutputStream() jsou
použity pro přístup k vstupnímu a výstupnímu streamu spojenému se socketem.
- close() se používá pro uzavření socketu.
- getSoLinger()
setSoLinger() se používají pro manipulaci s parametrem SO_LINGER, který
určuje, jak dlouho bude socket otevřen po vyvolání metody close() a jak
dlouho po uzavření budou moci být přenášena data.
- getSoTimeout() a
setSoTimeout() se používají pro manipulaci s parametrem SO_TIMEOUT,
který určuje, jak dlouho bude blokována operace read() nad socketem.
Nebo jinak za jak dlouho nastane timeout, který odblokuje operaci read().
- getTcpNoDelay() a
setTcpNoDelay() se používají pro manipulaci s parametrem TCP_NODELAY,
který specifikuje, bude-li Nagleův algoritmus, určující způsob manipulace
s daty v bufferech TCP spojení, zapnut nebo vypnut. Je-li TCP_NODELAY true,
je zakázán.
- setSocketImplFactory()
je použit k přepnutí z implicitní realizace Java socketu na uživatelskou
implementaci socketu.
- toString() vrací znakovou reprezentaci socketu.
Následující program
PortTalkApp.java je určen ke komunikaci se
vzdáleným počítačem. Dovoluje vysílat řádky textu, přijímat řádky textu a
ukončovat spojení.