Partage de technologie

Points de connaissances clés avancés Java-23-Programmation réseau

2024-07-12

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

Introduction à la programmation réseau

structure du logiciel

  • Structure C/S : Le nom complet est Structure Client/Serveur, qui fait référence à la structure client et serveur.
  • Structure B/S : le nom complet est Structure navigateur/serveur, qui fait référence à la structure du navigateur et du serveur.

Protocole de communication réseau

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

  • Protocole TCP/IP : Transmission Control Protocol/Internet Protocol (Transmission Control Protocol/Internet Protocol), est
    Le protocole le plus basique et le plus répandu d’Internet.
    Insérer la description de l'image ici

Classification du protocole

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

  1. TCP : Protocole de contrôle de transmission. Le protocole TCP est un protocole de communication orienté connexion, c'est-à-dire qu'avant de transmettre des données, une connexion logique est établie entre l'extrémité émettrice et l'extrémité réceptrice, puis les données sont transmises de manière fiable et sans erreur entre les deux. des ordinateurs.
  2. UDP : Protocole de datagramme utilisateur. Le protocole UDP est un protocole sans connexion. Lors de la transmission de données, il n'est pas nécessaire d'établir une connexion. Que le service de l'autre partie soit démarré ou non, les données, la source des données et la destination sont directement encapsulées dans le paquet de données et envoyées directement. La taille de chaque paquet est limitée à 64 Ko. Il s’agit d’un protocole peu fiable car il n’y a pas de connexion, la vitesse de transmission est donc rapide, mais les données sont facilement perdues.

Prise de contact à trois dans TCP : Dans le protocole TCP, lors de la phase de préparation de l'envoi des données, il existe trois interactions entre le client et le serveur pour assurer la fiabilité de la connexion.

  • Lors de la première poignée de main, le client envoie une demande de connexion au serveur et attend la confirmation du serveur.
  • Lors de la deuxième négociation, le serveur renvoie une réponse au client, l'informant que la demande de connexion a été reçue.
  • Lors de la troisième poignée de main, le client envoie à nouveau les informations de confirmation au serveur pour confirmer la connexion.

Trois éléments de la programmation réseau

  1. Protocole : les règles que les communications sur les réseaux informatiques doivent respecter
  2. Adresse IP : désigne l'adresse de protocole Internet, communément appelée IP. Les adresses IP sont utilisées pour numéroter de manière unique les appareils informatiques sur un réseau.
  • IPv4 : Il s'agit d'un nombre binaire de 32 bits, généralement divisé en 4 octets, exprimé sous la forme abcd, tel que 192.168.65.100. Parmi eux, a, b, c et d sont tous des nombres entiers décimaux compris entre 0 et 255, donc jusqu'à 4,2 milliards peuvent être représentés.
  • En utilisant une longueur d'adresse de 128 bits, chaque groupe de 16 octets est divisé en 8 groupes de nombres hexadécimaux, exprimés comme ABCD:EF01:2345:6789:ABCD:EF01:2345:6789, ce qui résout le problème des ressources d'adresse réseau insuffisantes. .
    Commandes couramment utilisées :
  • ipconfig [Afficher l'adresse IP locale]
    Insérer la description de l'image ici
  • Pingez l'adresse IP de l'espace [vérifiez si le réseau est connecté]
  1. Le numéro de port
  • Entier représenté par deux octets, sa plage de valeurs est comprise entre 0 et 65 535.Parmi eux, les numéros de port compris entre 0 et 1023 sont utilisés par certains réseaux bien connus
    Services et applications réseau, les applications ordinaires doivent utiliser des numéros de port supérieurs à 1024. Si le numéro de port est occupé par un autre service ou application, le programme en cours ne démarrera pas.
    Identifiez les processus dans le réseau : 协议 + IP地址 + 端口号

Programme de communication TCP

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

Étapes de communication

  • Le programme serveur doit être démarré à l'avance et attend la connexion du client.
  • Le client se connecte activement au serveur et ne peut communiquer que si la connexion réussit. Le serveur ne peut pas se connecter activement au client.

En Java, deux classes sont fournies pour implémenter les programmes de communication TCP :

  1. Client : Représenté par la classe java.net.Socket. Créez un objet Socket, envoyez une demande de connexion au serveur, le serveur répond à la demande, et les deux établissent une connexion et démarrent la communication.
  2. Serveur : représenté par la classe java.net.ServerSocket. Créer un objet ServerSocket équivaut à démarrer un service et à attendre que le client se connecte.

Classe de socket

Socket 类:该类实现客户端套接字,套接字指的是两台设备之间通讯的端点。
Méthode de construction :
public Socket(String host, int port) :Crée un objet socket et le connecte au numéro de port spécifié sur l'hôte spécifié. Si l'hôte spécifié est nul, cela équivaut à ce que l'adresse spécifiée soit l'adresse de bouclage (L'adresse de bouclage (127.xxx) est l'adresse de bouclage locale (Loopback Address))。
Méthodes de membre :

  • public InputStream getInputStream() : renvoie le flux d'entrée pour ce socket.
  • public OutputStream getOutputStream() : Renvoie le flux de sortie pour ce socket.
  • public void close() : Fermez cette prise.
  • public void shutdownOutput() : Désactive le flux de sortie pour ce socket.

Classe ServerSocket

ServerSocket 类:这个类实现了服务器套接字,该对象等待通过网络的请求。
Méthode de construction :
public ServerSocket (int port) : utilisez ce constructeur pour le lier à un pointeur lors de la création d'un objet ServerSocket.
Sur un certain numéro de port, le paramètre port est le numéro de port.
Méthodes de membre :
public Socket accept() : écoutez et acceptez les connexions, et renvoyez un nouvel objet Socket pour la communication avec le client.cette méthode
Bloquera jusqu'à ce que la connexion soit établie.

Programme réseau TCP simple

Analyse des communications TCP :

  1. [Serveur] Démarrez, créez l'objet ServerSocket et attendez la connexion.
  2. [Client] Démarrez, créez un objet Socket et demandez une connexion.
  3. [Serveur] reçoit la connexion, appelle la méthode accept et renvoie un objet Socket.
  4. [Client] Objet Socket, obtient OutputStream et écrit les données sur le serveur.
  5. [Serveur] Objet Socket, obtient le InputStream et lit les données envoyées par le client.
  6. [Serveur] Objet Socket, obtient OutputStream et réécrit les données sur le client.
  7. [Client] Objet Scoket, obtient InputStream, analyse et réécrit les données.
  8. [Client] Libérez les ressources et déconnectez-vous.

Exemple de code :

  • Terminal de service :
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

Le serveur spécifie le numéro de port, obtient l'objet Socket via la méthode accept(), obtient le flux d'entrée via l'objet client, et enfin lit les données et attend le message envoyé par le client.

  • client
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

Lorsque le client est créé, spécifiez l'adresse IP et le numéro de port de la connexion pour faciliter la connexion au serveur, obtenez le flux de sortie et les données de sortie via l'objet Socket client.
Insérer la description de l'image ici

Téléchargement de fichiers [étendu]

  1. [Client] Flux d'entrée, lit les données du fichier du disque dur dans le programme.
  2. [Client] Flux de sortie, écriture des données du fichier sur le serveur.
  3. [Serveur] Flux d'entrée, lecture des données du fichier sur le programme serveur.
  4. [Serveur] Flux de sortie, écriture des données du fichier sur le disque dur du serveur.
  5. [Serveur] Récupérez le flux de sortie et réécrivez les données.
  6. [Client] Obtenez le flux d'entrée, analysez et réécrivez les données.

数据准备:Placez un fichier nommé test.jpg sous le lecteur D et créez un dossier de test

Exemple de code :

  • Serveur
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

Ici, nous créons d'abord un objet serveur, utilisons while(true) pour assurer une connexion continue au serveur, puis démarrons un thread pour garantir que lorsqu'un utilisateur télécharge un fichier volumineux, l'efficacité des autres utilisateurs téléchargeant des fichiers ne sera pas affectée. Utilisez les millisecondes du système + « .jpg » pour définir le nom du fichier afin de garantir que le nom du fichier ne sera pas écrasé en raison du même nom de fichier lors du téléchargement.

  • client
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

Insérer la description de l'image ici
Insérer la description de l'image ici
Ici, nous pouvons voir que notre serveur a enregistré avec succès le fichier envoyé par l'utilisateur sur le disque dur.

Les amateurs de Java sont invités à en savoir plus sur l'article. L'auteur continuera à le mettre à jour et attend avec impatience votre attention et votre collection. . .