Technologieaustausch

Java Advanced Key Knowledge Points-23-Netzwerkprogrammierung

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Einführung in die Netzwerkprogrammierung

Softwarestruktur

  • C/S-Struktur: Der vollständige Name lautet Client/Server-Struktur und bezieht sich auf die Client- und Serverstruktur.
  • B/S-Struktur: Der vollständige Name lautet Browser/Server-Struktur und bezieht sich auf die Browser- und Serverstruktur.

Netzwerkkommunikationsprotokoll

网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信。

  • TCP/IP-Protokoll: Transmission Control Protocol/Internet Protocol (Transmission Control Protocol/Internet Protocol).
    Das grundlegendste und am weitesten verbreitete Protokoll des Internets.
    Fügen Sie hier eine Bildbeschreibung ein

Protokollklassifizierung

java.net 包中提供了两种常见的网络协议的支持

  1. TCP: Transmission Control Protocol. Das TCP-Protokoll ist ein verbindungsorientiertes Kommunikationsprotokoll, das heißt, vor der Datenübertragung wird eine logische Verbindung zwischen dem sendenden Ende und dem empfangenden Ende hergestellt und anschließend werden die Daten übertragen. Es ermöglicht eine zuverlässige und fehlerfreie Datenübertragung zwischen beiden Computers.
  2. UDP: Benutzer-Datagramm-Protokoll. Das UDP-Protokoll ist ein verbindungsloses Protokoll. Bei der Datenübertragung ist kein Verbindungsaufbau erforderlich. Unabhängig davon, ob der Dienst der anderen Partei gestartet ist, werden die Daten, die Datenquelle und das Ziel direkt im Datenpaket gekapselt und direkt gesendet. Die Größe jedes Pakets ist auf 64 KB begrenzt. Es handelt sich um ein unzuverlässiges Protokoll, da keine Verbindung besteht und die Übertragungsgeschwindigkeit daher hoch ist, Daten jedoch leicht verloren gehen.

Drei-Wege-Handshake in TCP: Im TCP-Protokoll gibt es in der Vorbereitungsphase des Sendens von Daten drei Interaktionen zwischen dem Client und dem Server, um die Zuverlässigkeit der Verbindung sicherzustellen.

  • Beim ersten Handshake sendet der Client eine Verbindungsanfrage an den Server und wartet auf die Bestätigung vom Server.
  • Beim zweiten Handshake sendet der Server eine Antwort an den Client zurück und benachrichtigt den Client, dass die Verbindungsanforderung empfangen wurde.
  • Beim dritten Handshake sendet der Client erneut Bestätigungsinformationen an den Server, um die Verbindung zu bestätigen.

Drei Elemente der Netzwerkprogrammierung

  1. Protokoll: Die Regeln, die bei der Computernetzwerkkommunikation eingehalten werden müssen
  2. IP-Adresse: bezieht sich auf die Internetprotokolladresse, allgemein bekannt als IP. IP-Adressen werden verwendet, um Computergeräte in einem Netzwerk eindeutig zu nummerieren.
  • IPv4: Es handelt sich um eine 32-Bit-Binärzahl, die normalerweise in 4 Bytes unterteilt ist und in der Form abcd ausgedrückt wird, z. B. 192.168.65.100. Unter diesen sind a, b, c und d alle dezimale ganze Zahlen zwischen 0 und 255, sodass bis zu 4,2 Milliarden dargestellt werden können.
  • Unter Verwendung einer Adresslänge von 128 Bit wird jede Gruppe von 16 Bytes in 8 Gruppen hexadezimaler Zahlen unterteilt, ausgedrückt als ABCD:EF01:2345:6789:ABCD:EF01:2345:6789, wodurch das Problem unzureichender Netzwerkadressressourcen gelöst wird.
    Häufig verwendete Befehle:
  • ipconfig [Lokale IP-Adresse anzeigen]
    Fügen Sie hier eine Bildbeschreibung ein
  • Pingen Sie die Space-IP-Adresse an [überprüfen Sie, ob das Netzwerk verbunden ist]
  1. Die Portnummer
  • Eine durch zwei Bytes dargestellte Ganzzahl, ihr Wertebereich liegt zwischen 0 und 65535.Darunter werden Portnummern zwischen 0 und 1023 von einigen bekannten Netzwerken verwendet
    Netzwerkdienste und -anwendungen, normale Anwendungen müssen Portnummern über 1024 verwenden. Wenn die Portnummer von einem anderen Dienst oder einer anderen Anwendung belegt ist, kann das aktuelle Programm nicht gestartet werden.
    Prozesse im Netzwerk identifizieren: 协议 + IP地址 + 端口号

TCP-Kommunikationsprogramm

TCP通信能实现两台计算机之间的数据交互,通信的两端,要严格区分为客户端(Client)与服务端(Server)。

Kommunikationsschritte

  • Das Serverprogramm muss vorher gestartet werden und wartet auf die Verbindung des Clients.
  • Der Client verbindet sich aktiv mit dem Server und kann nur kommunizieren, wenn die Verbindung erfolgreich ist. Der Server kann keine aktive Verbindung zum Client herstellen.

In Java werden zwei Klassen zur Implementierung von TCP-Kommunikationsprogrammen bereitgestellt:

  1. Client: Repräsentiert durch die Klasse java.net.Socket. Erstellen Sie ein Socket-Objekt, senden Sie eine Verbindungsanforderung an den Server, der Server antwortet auf die Anforderung und die beiden stellen eine Verbindung her und beginnen mit der Kommunikation.
  2. Server: dargestellt durch die Klasse java.net.ServerSocket. Das Erstellen eines ServerSocket-Objekts entspricht dem Starten eines Dienstes und dem Warten auf die Verbindung des Clients.

Socket-Klasse

Socket 类:该类实现客户端套接字,套接字指的是两台设备之间通讯的端点。
Konstruktionsmethode:
public Socket(String host, int port) :Erstellt ein Socket-Objekt und verbindet es mit der angegebenen Portnummer auf dem angegebenen Host. Wenn der angegebene Host null ist, entspricht dies der angegebenen Adresse als Loopback-Adresse (Die Loopback-Adresse (127.xxx) ist die lokale Loopback-Adresse (Loopback-Adresse).)。
Mitgliedsmethoden:

  • public InputStream getInputStream() : Gibt den Eingabestream für diesen Socket zurück.
  • public OutputStream getOutputStream() : Gibt den Ausgabestream für diesen Socket zurück.
  • public void close() : Schließen Sie diesen Socket.
  • public void shutdownOutput() : Deaktiviert den Ausgabestream für diesen Socket.

ServerSocket-Klasse

ServerSocket 类:这个类实现了服务器套接字,该对象等待通过网络的请求。
Konstruktionsmethode:
public ServerSocket(int port): Verwenden Sie diesen Konstruktor, um ihn beim Erstellen eines ServerSocket-Objekts an einen Zeiger zu binden.
Bei einer bestimmten Portnummer ist der Parameter Port die Portnummer.
Mitgliedsmethoden:
public Socket accept() : Verbindungen abhören und akzeptieren und ein neues Socket-Objekt für die Kommunikation mit dem Client zurückgeben.diese Methode
Wird blockiert, bis die Verbindung hergestellt ist.

Einfaches TCP-Netzwerkprogramm

TCP-Kommunikationsanalyse:

  1. [Server] Starten Sie, erstellen Sie ein ServerSocket-Objekt und warten Sie auf die Verbindung.
  2. [Client] Starten, Socket-Objekt erstellen und Verbindung anfordern.
  3. [Server] empfängt die Verbindung, ruft die Accept-Methode auf und gibt ein Socket-Objekt zurück.
  4. [Client] Socket-Objekt, ruft OutputStream ab und schreibt Daten auf den Server.
  5. [Server] Socket-Objekt, ruft den InputStream ab und liest die vom Client gesendeten Daten.
  6. [Server] Socket-Objekt, ruft OutputStream ab und schreibt Daten zurück an den Client.
  7. [Client] Scoket-Objekt, ruft InputStream ab, analysiert Daten und schreibt sie zurück.
  8. [Client] Ressourcen freigeben und trennen.

Codebeispiel:

  • Service-Terminal:
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTCP {
    public static void main(String[] args) throws IOException {
        System.out.println("服务端启动 , 等待连接 .... ");
        // 1.创建 ServerSocket对象,绑定端口,开始等待连接
        ServerSocket ss = new ServerSocket(6666);
        // 2.接收连接 accept 方法, 返回 socket 对象.
        Socket server = ss.accept();
        // 3.通过socket 获取输入流
        InputStream is = server.getInputStream();
        // 4.一次性读取数据
        // 4.1 创建字节数组
        byte[] b = new byte[1024];
        // 4.2 据读取到字节数组中.
        int len = is.read(b);
        // 4.3 解析数组,打印字符串信息
        String msg = new String(b, 0, len);
        System.out.println(msg);
        //5.关闭资源.
        is.close();
        server.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

Der Server gibt die Portnummer an, ruft das Socket-Objekt über die Methode Accept () ab, ruft den Eingabestream über das Client-Objekt ab und liest schließlich die Daten und wartet auf die vom Client gesendete Nachricht.

  • Klient
import java.net.Socket;

public class ClientTCP {
    public static void main(String[] args) throws Exception {
        System.out.println("客户端 发送数据");
        // 1.创建 Socket ( ip , port ) , 确定连接到哪里.
        Socket client = new Socket("localhost", 6666);
        // 2.获取流对象 . 输出流
        OutputStream os = client.getOutputStream();
        // 3.写出数据.
        os.write("你好么? tcp ,我来了".getBytes());
        // 4. 关闭资源 .
        os.close();
        client.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Geben Sie beim Erstellen des Clients die IP-Adresse und die Portnummer der Verbindung an, um die Verbindung zum Server zu erleichtern, den Ausgabestream abzurufen und Daten über das Client-Socket-Objekt auszugeben.
Fügen Sie hier eine Bildbeschreibung ein

Datei-Upload [Erweitert]

  1. [Client] Eingabestream, Dateidaten von der Festplatte in das Programm einlesen.
  2. [Client] Ausgabestream, Dateidaten auf den Server schreiben.
  3. [Server] Eingabestream, Dateidaten in das Serverprogramm lesen.
  4. [Server] Ausgabestream, Dateidaten auf die Serverfestplatte schreiben.
  5. [Server] Holen Sie sich den Ausgabestream und schreiben Sie die Daten zurück.
  6. [Client] Rufen Sie den Eingabestream ab, analysieren Sie die Daten und schreiben Sie sie zurück.

数据准备:Legen Sie eine Datei mit dem Namen test.jpg auf dem Laufwerk D ab und erstellen Sie einen Testordner

Codebeispiel:

  • Server
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class FileUpload_Server {
    public static void main(String[] args) throws IOException {
        System.out.println("服务器 启动..... ");
        // 1. 创建服务端ServerSocket
        ServerSocket serverSocket = new ServerSocket(6666);
        // 2. 循环接收,建立连接
        while (true) {
        Socket accept = serverSocket.accept();
            /* 3. socket对象交给子线程处理,进行读写操作Runnable接口中,只有一个run方法,使用lambda表达式简化格式 */
            new Thread(() -> {
                try (   //3.1 获取输入流对象
                        BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
                        //3.2 创建输出流对象, 保存到本地 .
                        FileOutputStream fis = new FileOutputStream("D:/test/" + System.currentTimeMillis() + ".jpg");
                        BufferedOutputStream bos = new BufferedOutputStream(fis)) {
                    // 3.3 读写数据
                    byte[] b = new byte[1024 * 8];
                    int len;
                    while ((len = bis.read(b)) != -1) {
                        bos.write(b, 0, len);
                    }

                    // 4.=======信息回写===========================
                    System.out.println("back ........");
                    OutputStream out = accept.getOutputStream();
                    out.write("上传成功".getBytes());
                    out.close();

                    //5. 关闭 资源
                    bos.close();
                    bis.close();
                    accept.close();
                    System.out.println("文件上传已保存");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

Hier erstellen wir zunächst ein Serverobjekt, verwenden while (true), um eine kontinuierliche Verbindung zum Server sicherzustellen, und starten dann einen Thread, um sicherzustellen, dass die Effizienz anderer Benutzer beim Hochladen von Dateien nicht beeinträchtigt wird, wenn ein Benutzer eine große Datei hochlädt. Verwenden Sie die System-Millisekunden + „.jpg“, um den Dateinamen festzulegen, um sicherzustellen, dass der Dateiname beim Hochladen nicht aufgrund des gleichen Dateinamens überschrieben wird.

  • Klient
import java.io.*;
import java.net.Socket;

public class FileUpload_Client {
    public static void main(String[] args) throws IOException {
        // 1.创建流对象
        // 1.1 创建输入流,读取本地文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\test.jpg"));
        // 1.2 创建输出流,写到服务端
        Socket socket = new Socket("localhost", 6666);
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        //2.写出数据.
        byte[] b = new byte[1024 * 8 ];
        int len ;
        while (( len = bis.read(b))!=-1) {
            bos.write(b, 0, len);
        }
        // 关闭输出流,通知服务端,写出数据完毕
        socket.shutdownOutput();
        System.out.println("文件发送完毕");   
        // 3. =====解析回写============
        InputStream in = socket.getInputStream();
        byte[] back = new byte[20];
        in.read(back);
        System.out.println(new String(back));
        in.close();
        // ============================
        // 4.释放资源
        socket.close();
        bis.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Hier können wir sehen, dass unser Server die vom Benutzer gesendete Datei erfolgreich auf der Festplatte gespeichert hat.

Java-Liebhaber sind herzlich eingeladen, sich über den Artikel zu informieren. Der Autor wird ihn weiterhin aktualisieren und freut sich auf Ihre Aufmerksamkeit und Sammlung. . .