Java-Netzwerkprogrammierung

Netzwerkprogrammierung bezieht sich auf das Schreiben von Programmen, die auf mehreren Geräten (Computern) ausgeführt werden, die alle über ein Netzwerk verbunden sind.

Die J2SE-APIs im Paket java.net enthalten Klassen und Schnittstellen, die Details der Kommunikation auf niedriger Ebene bereitstellen. Sie können diese Klassen und Schnittstellen direkt verwenden, um sich auf die Lösung von Problemen zu konzentrieren, ohne sich um Kommunikationsdetails kümmern zu müssen.

Das Paket java.net bietet Unterstützung für zwei gängige Netzwerkprotokolle:

  • TCP: TCP (Transmission Control Protocol) ist ein verbindungsorientiertes, zuverlässiges, Byte-Stream-basiertes Kommunikationsprotokoll der Transportschicht. Die TCP-Schicht ist eine Zwischenschicht, die über der IP-Schicht und unter der Anwendungsschicht liegt. TCP gewährleistet eine zuverlässige Kommunikation zwischen zwei Anwendungen. Es wird häufig für Internetprotokolle verwendet und als TCP/IP bezeichnet.

  • UDP: UDP (User Datagram Protocol) befindet sich auf der Transportschicht des OSI-Modells. Es ist ein verbindungsloses Protokoll. Es stellt Datagramme zum Senden von Daten zwischen Anwendungen bereit. Da UDP keine Zuverlässigkeit bietet und ein verbindungsloses Protokoll ist, müssen Anwendungen normalerweise einige verlorene, fehlerhafte oder doppelte Pakete tolerieren.

Dieses Tutorial behandelt hauptsächlich die folgenden zwei Themen.

  • Socket-Programmierung: Dies ist das am weitesten verbreitete Netzwerkkonzept und wurde ausführlich erklärt.

  • URL-Verarbeitung: Dieser Teil wird in einem separaten Abschnitt behandelt. Klicken Sie hier, um mehr überURL-Verarbeitung in der Java-Sprache zu erfahren.。


Socket-Programmierung

Sockets verwenden TCP, um einen Kommunikationsmechanismus zwischen zwei Computern bereitzustellen. Ein Client-Programm erstellt einen Socket und versucht, eine Verbindung zum Socket des Servers herzustellen.

Wenn die Verbindung hergestellt ist, erstellt der Server ein Socket-Objekt. Client und Server können nun kommunizieren, indem sie in die Socket-Objekte schreiben und daraus lesen.

Die Klasse java.net.Socket repräsentiert einen Socket, und die Klasse java.net.ServerSocket bietet einen Mechanismus für Serverprogramme, auf Clients zu lauschen und Verbindungen mit ihnen herzustellen.

Die folgenden Schritte erfolgen beim Aufbau einer TCP-Verbindung zwischen zwei Computern über Sockets:

  • Der Server instanziiert ein ServerSocket-Objekt, das die Kommunikation über einen Port auf dem Server angibt.

  • Der Server ruft die Methode accept() der Klasse ServerSocket auf, die wartet, bis ein Client eine Verbindung zum angegebenen Port auf dem Server herstellt.

  • Während der Server wartet, instanziiert ein Client ein Socket-Objekt, wobei er den Servernamen und die Portnummer angibt, um eine Verbindung anzufordern.

  • Der Konstruktor der Klasse Socket versucht, den Client mit dem angegebenen Server und der Portnummer zu verbinden. Wenn die Kommunikation hergestellt ist, wird auf dem Client ein Socket-Objekt erstellt, das mit dem Server kommunizieren kann.

  • Auf der Serverseite gibt die Methode accept() eine neue Socket-Referenz auf dem Server zurück, die mit dem Socket des Clients verbunden ist.

Nachdem die Verbindung hergestellt ist, erfolgt die Kommunikation über I/O-Streams. Jeder Socket hat einen Ausgabestream und einen Eingabestream. Der Ausgabestream des Clients verbindet sich mit dem Eingabestream des Servers, während der Eingabestream des Clients mit dem Ausgabestream des Servers verbunden wird.

TCP ist ein bidirektionales Kommunikationsprotokoll, daher können Daten gleichzeitig über beide Datenströme gesendet werden. Im Folgenden finden Sie einige Klassen, die einen vollständigen Satz nützlicher Methoden für die Implementierung von Sockets bereitstellen.


Methoden der Klasse ServerSocket

Serveranwendungen verwenden die Klasse java.net.ServerSocket, um einen Port zu beziehen und auf Client-Anfragen zu lauschen.

Die Klasse ServerSocket hat vier Konstruktoren:

Nein. Methodenbeschreibung
1 public ServerSocket(int port) throws IOException
Erstellt einen Server-Socket, der an einen bestimmten Port gebunden ist.
2 public ServerSocket(int port, int backlog) throws IOException
Erstellt einen Server-Socket mit dem angegebenen Backlog und bindet ihn an die angegebene lokale Portnummer.
3 public ServerSocket(int port, int backlog, InetAddress address) throws IOException
Erstellt einen Server unter Verwendung des angegebenen Ports, des Listen-Backlogs und der lokalen IP-Adresse, an die gebunden werden soll.
4 public ServerSocket() throws IOException
Erzeugt einen ungebundenen Server-Socket.

Erzeugt einen ungebundenen Server-Socket. Wenn der ServerSocket-Konstruktor keine Ausnahme auslöst, bedeutet das, dass Ihre Anwendung erfolgreich an den angegebenen Port gebunden wurde und auf Client-Anfragen lauscht.

Hier sind einige gängige Methoden der ServerSocket-Klasse:

Nein. Methodenbeschreibung
1 public int getLocalPort()
Gibt den Port zurück, auf dem dieser Socket lauscht.
2 public Socket accept() throws IOException
Lauscht auf Verbindungen zu diesem Socket und akzeptiert sie.
3 public void setSoTimeout(int timeout)
Aktiviert/deaktiviert SO_TIMEOUT mit dem angegebenen Timeout-Wert in Millisekunden.
4 public void bind(SocketAddress host, int backlog)
Bindet den ServerSocket an eine bestimmte Adresse (IP-Adresse und Portnummer).

Methoden der Socket-Klasse

Die Klasse java.net.Socket repräsentiert den Socket, der sowohl vom Client als auch vom Server zur gegenseitigen Kommunikation verwendet wird. Der Client erhält ein Socket-Objekt, indem er eines instanziiert, während der Server ein Socket-Objekt über den Rückgabewert der accept()-Methode erhält.

Die Socket-Klasse hat fünf Konstruktoren.

Nein. Methodenbeschreibung
1 public Socket(String host, int port) throws UnknownHostException, IOException.
Erstellt einen Stream-Socket und verbindet ihn mit der angegebenen Portnummer auf dem angegebenen Host.
2 public Socket(InetAddress host, int port) throws IOException
Erstellt einen Stream-Socket und verbindet ihn mit der angegebenen Portnummer auf der angegebenen IP-Adresse.
3 public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException.
Erstellt einen Socket und verbindet ihn mit dem angegebenen entfernten Port auf dem angegebenen entfernten Host.
4 public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException.
Erstellt einen Socket und verbindet ihn mit dem angegebenen entfernten Port an der angegebenen entfernten Adresse.
5 public Socket()
Erstellt einen nicht verbundenen Socket unter Verwendung des systemstandardmäßigen Typs von SocketImpl.

Wenn der Socket-Konstruktor zurückkehrt, instanziiert er nicht einfach ein Socket-Objekt; er versucht tatsächlich, eine Verbindung zum angegebenen Server und Port herzustellen.

Einige interessante Methoden sind unten aufgeführt. Beachten Sie, dass sowohl der Client als auch der Server über ein Socket-Objekt verfügen, sodass sowohl der Client als auch der Server diese Methoden aufrufen können.

Nein. Methodenbeschreibung
1 public void connect(SocketAddress host, int timeout) throws IOException
Verbindet diesen Socket mit dem Server und gibt einen Timeout-Wert an.
2 public InetAddress getInetAddress()
Gibt die Adresse zurück, mit der dieser Socket verbunden ist.
3 public int getPort()
Gibt den entfernten Port zurück, mit dem dieser Socket verbunden ist.
4 public int getLocalPort()
Gibt den lokalen Port zurück, an den dieser Socket gebunden ist.
5 public SocketAddress getRemoteSocketAddress()
Gibt die Adresse des Endpunkts zurück, mit dem dieser Socket verbunden ist, oder null, wenn er nicht verbunden ist.
6 public InputStream getInputStream() throws IOException
Gibt den Eingabestrom dieses Sockets zurück.
7 public OutputStream getOutputStream() throws IOException
Gibt den Ausgabestrom dieses Sockets zurück.
8 public void close() throws IOException
Schließt diesen Socket.

Methoden der Klasse InetAddress

Diese Klasse repräsentiert eine Internetprotokoll-Adresse (IP-Adresse). Im Folgenden sind einige nützliche Methoden für die Socket-Programmierung aufgeführt:

Nein. Methodenbeschreibung
1 static InetAddress getByAddress(byte[] addr)
Gibt ein InetAddress-Objekt für die angegebene rohe IP-Adresse zurück.
2 static InetAddress getByAddress(String host, byte[] addr)
Erstellt eine InetAddress anhand des angegebenen Hostnamens und der IP-Adresse.
3 static InetAddress getByName(String host)
Ermittelt die IP-Adresse eines Hosts anhand des Hostnamens.
4 String getHostAddress() 
Gibt die Zeichenfolge der IP-Adresse (in Textform) zurück.
5 String getHostName() 
Ruft den Hostnamen für diese IP-Adresse ab.
6 static InetAddress getLocalHost()
Gibt den lokalen Host zurück.
7 String toString()
Konvertiert diese IP-Adresse in einen String.

Socket-Client-Beispiel

Der folgende GreetingClient ist ein Client-Programm, das über einen Socket eine Verbindung zu einem Server herstellt, eine Anfrage sendet und dann auf eine Antwort wartet.

Code der Datei GreetingClient.java:

//Dateiname: 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("Verbindung zu Host:" + serverName + ", Portnummer:" + port); Socket client = new Socket(serverName, port); System.out.println("Adresse des Remote-Hosts:" + client.getRemoteSocketAddress()); OutputStream outToServer = client.getOutputStream(); DataOutputStream out = new DataOutputStream(outToServer); out.writeUTF("Hallo von " + client.getLocalSocketAddress()); InputStream inFromServer = client.getInputStream(); DataInputStream in = new DataInputStream(inFromServer); System.out.println("Serverantwort:" + in.readUTF()); client.close(); }catch(IOException e) { e.printStackTrace(); } } }

Socket-Server-Beispiel

Das folgende GreetingServer-Programm ist eine serverseitige Anwendung, die einen Socket verwendet, um auf einem angegebenen Port zu lauschen.

Code der Datei GreetingServer.java:

//Dateiname: 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("Warte auf Remote-Verbindung, Portnummer:" + serverSocket.getLocalPort() + "..."); Socket server = serverSocket.accept(); System.out.println("Remote-Host-Adresse:" + server.getRemoteSocketAddress()); DataInputStream in = new DataInputStream(server.getInputStream()); System.out.println(in.readUTF()); DataOutputStream out = new DataOutputStream(server.getOutputStream()); out.writeUTF("Danke für die Verbindung zu mir:" + server.getLocalSocketAddress() + "\nAuf Wiedersehen!"); server.close(); }catch(SocketTimeoutException s) { System.out.println("Socket-Zeitüberschreitung!"); 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.run(); }catch(IOException e) { e.printStackTrace(); } } }

Kompilieren Sie die beiden oben genannten Java-Dateicodes und führen Sie die folgenden Befehle aus, um den Dienst mit der Portnummer 6066 zu starten:

$ javac GreetingServer.java 
$ java GreetingServer 6066
等待远程连接,端口号为:6066...

Öffnen Sie ein neues Befehlsfenster und führen Sie den obigen Befehl aus, um den Client zu starten:

$ javac GreetingClient.java 
$ java GreetingClient localhost 6066
连接到主机:localhost ,端口号:6066
远程主机地址:localhost/127.0.0.1:6066
服务器响应: 谢谢连接我:/127.0.0.1:6066
Goodbye!
Weitere Erweiterungen