Java - Vernetzung
Der Begriff Netzwerkprogrammierung bezieht sich auf das Schreiben von Programmen, die auf mehreren Geräten (Computern) ausgeführt werden, bei denen alle Geräte über ein Netzwerk miteinander verbunden sind.
Das java.net-Paket der J2SE-APIs enthält eine Sammlung von Klassen und Schnittstellen, die die Kommunikationsdetails auf niedriger Ebene bereitstellen, sodass Sie Programme schreiben können, die sich auf die Lösung des vorliegenden Problems konzentrieren.
Das java.net-Paket bietet Unterstützung für die beiden gängigen Netzwerkprotokolle -
TCP- TCP steht für Transmission Control Protocol, das eine zuverlässige Kommunikation zwischen zwei Anwendungen ermöglicht. TCP wird normalerweise über das Internetprotokoll verwendet, das als TCP / IP bezeichnet wird.
UDP - UDP steht für User Datagram Protocol, ein verbindungsloses Protokoll, mit dem Datenpakete zwischen Anwendungen übertragen werden können.
Dieses Kapitel vermittelt ein gutes Verständnis der folgenden beiden Themen:
Socket Programming - Dies ist das am weitesten verbreitete Konzept in der Vernetzung und wurde sehr ausführlich erläutert.
URL Processing- Dies würde separat behandelt. Klicken Sie hier, um mehr über die URL-Verarbeitung in Java zu erfahren .
Socket-Programmierung
Sockets stellen den Kommunikationsmechanismus zwischen zwei Computern mithilfe von TCP bereit. Ein Client-Programm erstellt am Ende der Kommunikation einen Socket und versucht, diesen Socket mit einem Server zu verbinden.
Wenn die Verbindung hergestellt ist, erstellt der Server am Ende der Kommunikation ein Socket-Objekt. Der Client und der Server können jetzt kommunizieren, indem sie in den Socket schreiben und von diesem lesen.
Die Klasse java.net.Socket stellt einen Socket dar, und die Klasse java.net.ServerSocket bietet einen Mechanismus für das Serverprogramm, um auf Clients zu warten und Verbindungen mit ihnen herzustellen.
Die folgenden Schritte werden ausgeführt, wenn eine TCP-Verbindung zwischen zwei Computern mithilfe von Sockets hergestellt wird:
Der Server instanziiert ein ServerSocket-Objekt und gibt an, an welcher Portnummer die Kommunikation stattfinden soll.
Der Server ruft die accept () -Methode der ServerSocket-Klasse auf. Diese Methode wartet, bis ein Client am angegebenen Port eine Verbindung zum Server herstellt.
Nachdem der Server gewartet hat, instanziiert ein Client ein Socket-Objekt und gibt den Servernamen und die Portnummer an, zu der eine Verbindung hergestellt werden soll.
Der Konstruktor der Socket-Klasse versucht, den Client mit dem angegebenen Server und der Portnummer zu verbinden. Wenn die Kommunikation hergestellt ist, verfügt der Client jetzt über ein Socket-Objekt, das mit dem Server kommunizieren kann.
Auf der Serverseite gibt die accept () -Methode einen Verweis auf einen neuen Socket auf dem Server zurück, der mit dem Socket des Clients verbunden ist.
Nachdem die Verbindungen hergestellt wurden, kann die Kommunikation über E / A-Streams erfolgen. Jeder Socket hat sowohl einen OutputStream als auch einen InputStream. Der OutputStream des Clients ist mit dem InputStream des Servers verbunden, und der InputStream des Clients ist mit dem OutputStream des Servers verbunden.
TCP ist ein bidirektionales Kommunikationsprotokoll, daher können Daten gleichzeitig über beide Streams gesendet werden. Im Folgenden finden Sie die nützlichen Klassen, die einen vollständigen Satz von Methoden zum Implementieren von Sockets bereitstellen.
ServerSocket-Klassenmethoden
Das java.net.ServerSocket Die Klasse wird von Serveranwendungen verwendet, um einen Port abzurufen und auf Clientanforderungen zu warten.
Die ServerSocket-Klasse verfügt über vier Konstruktoren -
Sr.Nr. | Methode & Beschreibung |
---|---|
1 | public ServerSocket(int port) throws IOException Es wird versucht, einen Server-Socket zu erstellen, der an den angegebenen Port gebunden ist. Eine Ausnahme tritt auf, wenn der Port bereits an eine andere Anwendung gebunden ist. |
2 | public ServerSocket(int port, int backlog) throws IOException Ähnlich wie beim vorherigen Konstruktor gibt der Parameter backlog an, wie viele eingehende Clients in einer Warteschlange gespeichert werden sollen. |
3 | public ServerSocket(int port, int backlog, InetAddress address) throws IOException Ähnlich wie beim vorherigen Konstruktor gibt der Parameter InetAddress die lokale IP-Adresse an, an die gebunden werden soll. Die InetAddress wird für Server verwendet, die möglicherweise mehrere IP-Adressen haben, sodass der Server angeben kann, auf welcher seiner IP-Adressen Clientanforderungen akzeptiert werden sollen. |
4 | public ServerSocket() throws IOException Erstellt einen ungebundenen Server-Socket. Verwenden Sie bei Verwendung dieses Konstruktors die Methode bind (), wenn Sie bereit sind, den Server-Socket zu binden. |
Wenn der ServerSocket-Konstruktor keine Ausnahme auslöst, bedeutet dies, dass Ihre Anwendung erfolgreich an den angegebenen Port gebunden wurde und für Clientanforderungen bereit ist.
Im Folgenden sind einige der gängigen Methoden der ServerSocket-Klasse aufgeführt:
Sr.Nr. | Methode & Beschreibung |
---|---|
1 | public int getLocalPort() Gibt den Port zurück, den der Server-Socket abhört. Diese Methode ist nützlich, wenn Sie 0 als Portnummer in einem Konstruktor übergeben und den Server einen Port für Sie finden lassen. |
2 | public Socket accept() throws IOException Wartet auf einen eingehenden Client. Diese Methode wird blockiert, bis entweder ein Client über den angegebenen Port eine Verbindung zum Server herstellt oder das Socket eine Zeitüberschreitung aufweist, vorausgesetzt, der Zeitlimitwert wurde mit der Methode setSoTimeout () festgelegt. Andernfalls wird diese Methode auf unbestimmte Zeit blockiert. |
3 | public void setSoTimeout(int timeout) Legt den Timeout-Wert fest, wie lange der Server-Socket während der Annahme () auf einen Client wartet. |
4 | public void bind(SocketAddress host, int backlog) Bindet den Socket an den angegebenen Server und Port im SocketAddress-Objekt. Verwenden Sie diese Methode, wenn Sie den ServerSocket mit dem Konstruktor ohne Argumente instanziiert haben. |
Wenn der ServerSocket accept () aufruft, wird die Methode erst zurückgegeben, wenn ein Client eine Verbindung herstellt. Nachdem ein Client eine Verbindung hergestellt hat, erstellt der ServerSocket einen neuen Socket an einem nicht angegebenen Port und gibt einen Verweis auf diesen neuen Socket zurück. Zwischen dem Client und dem Server besteht jetzt eine TCP-Verbindung, und die Kommunikation kann beginnen.
Socket-Klassenmethoden
Das java.net.SocketKlasse stellt den Socket dar, über den sowohl der Client als auch der Server miteinander kommunizieren. Der Client erhält ein Socket-Objekt durch Instanziieren eines Objekts, während der Server ein Socket-Objekt aus dem Rückgabewert der accept () -Methode erhält.
Die Socket-Klasse verfügt über fünf Konstruktoren, mit denen ein Client eine Verbindung zu einem Server herstellt.
Sr.Nr. | Methode & Beschreibung |
---|---|
1 | public Socket(String host, int port) throws UnknownHostException, IOException. Diese Methode versucht, am angegebenen Port eine Verbindung zum angegebenen Server herzustellen. Wenn dieser Konstruktor keine Ausnahme auslöst, ist die Verbindung erfolgreich und der Client ist mit dem Server verbunden. |
2 | public Socket(InetAddress host, int port) throws IOException Diese Methode ist identisch mit dem vorherigen Konstruktor, außer dass der Host durch ein InetAddress-Objekt gekennzeichnet ist. |
3 | public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. Stellt eine Verbindung zum angegebenen Host und Port her und erstellt einen Socket auf dem lokalen Host unter der angegebenen Adresse und dem angegebenen Port. |
4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. Diese Methode ist identisch mit dem vorherigen Konstruktor, außer dass der Host durch ein InetAddress-Objekt anstelle eines Strings gekennzeichnet ist. |
5 | public Socket() Erstellt einen nicht verbundenen Socket. Verwenden Sie die connect () -Methode, um diesen Socket mit einem Server zu verbinden. |
Wenn der Socket-Konstruktor zurückkehrt, instanziiert er nicht einfach ein Socket-Objekt, sondern versucht tatsächlich, eine Verbindung zum angegebenen Server und Port herzustellen.
Einige interessante Methoden in der Socket-Klasse sind hier aufgelistet. Beachten Sie, dass sowohl der Client als auch der Server über ein Socket-Objekt verfügen, sodass diese Methoden sowohl vom Client als auch vom Server aufgerufen werden können.
Sr.Nr. | Methode & Beschreibung |
---|---|
1 | public void connect(SocketAddress host, int timeout) throws IOException Diese Methode verbindet den Socket mit dem angegebenen Host. Diese Methode wird nur benötigt, wenn Sie den Socket mit dem Konstruktor ohne Argumente instanziieren. |
2 | public InetAddress getInetAddress() Diese Methode gibt die Adresse des anderen Computers zurück, mit dem dieser Socket verbunden ist. |
3 | public int getPort() Gibt den Port zurück, an den der Socket auf dem Remotecomputer gebunden ist. |
4 | public int getLocalPort() Gibt den Port zurück, an den der Socket auf dem lokalen Computer gebunden ist. |
5 | public SocketAddress getRemoteSocketAddress() Gibt die Adresse des Remote-Sockets zurück. |
6 | public InputStream getInputStream() throws IOException Gibt den Eingabestream des Sockets zurück. Der Eingangsstrom ist mit dem Ausgangsstrom des Remote-Sockets verbunden. |
7 | public OutputStream getOutputStream() throws IOException Gibt den Ausgabestream des Sockets zurück. Der Ausgangsstrom ist mit dem Eingangsstrom des Remote-Sockets verbunden. |
8 | public void close() throws IOException Schließt den Socket, wodurch dieses Socket-Objekt keine Verbindung mehr zu einem Server herstellen kann. |
InetAddress-Klassenmethoden
Diese Klasse repräsentiert eine IP-Adresse (Internet Protocol). Hier sind die folgenden nützlichen Methoden, die Sie für die Socket-Programmierung benötigen würden:
Sr.Nr. | Methode & Beschreibung |
---|---|
1 | static InetAddress getByAddress(byte[] addr) Gibt ein InetAddress-Objekt mit der unformatierten IP-Adresse zurück. |
2 | static InetAddress getByAddress(String host, byte[] addr) Erstellt eine InetAddress basierend auf dem angegebenen Hostnamen und der angegebenen IP-Adresse. |
3 | static InetAddress getByName(String host) Bestimmt die IP-Adresse eines Hosts anhand des Hostnamens. |
4 | String getHostAddress() Gibt die IP-Adresszeichenfolge in Textdarstellung zurück. |
5 | String getHostName() Ruft den Hostnamen für diese IP-Adresse ab. |
6 | static InetAddress InetAddress getLocalHost() Gibt den lokalen Host zurück. |
7 | String toString() Konvertiert diese IP-Adresse in einen String. |
Beispiel für einen Socket-Client
Der folgende GreetingClient ist ein Client-Programm, das über einen Socket eine Verbindung zu einem Server herstellt, eine Begrüßung sendet und dann auf eine Antwort wartet.
Beispiel
// File Name GreetingClient.java
import java.net.*;
import java.io.*;
public class GreetingClient {
public static void main(String [] args) {
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try {
System.out.println("Connecting to " + serverName + " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Beispiel für einen Socket-Server
Das folgende GreetingServer-Programm ist ein Beispiel für eine Serveranwendung, die mithilfe der Socket-Klasse auf Clients wartet, deren Portnummer durch ein Befehlszeilenargument angegeben wird.
Beispiel
// File Name GreetingServer.java
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread {
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run() {
while(true) {
try {
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
+ "\nGoodbye!");
server.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String [] args) {
int port = Integer.parseInt(args[0]);
try {
Thread t = new GreetingServer(port);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Kompilieren Sie den Client und den Server und starten Sie den Server wie folgt:
$ java GreetingServer 6066
Waiting for client on port 6066...
Überprüfen Sie das Client-Programm wie folgt:
Ausgabe
$ java GreetingClient localhost 6066
Connecting to localhost on port 6066
Just connected to localhost/127.0.0.1:6066
Server says Thank you for connecting to /127.0.0.1:6066
Goodbye!