Compartir tecnología

Puntos de conocimiento clave avanzados de Java-23-Programación de redes

2024-07-12

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

Introducción a la programación de redes.

estructura del software

  • Estructura C/S: el nombre completo es estructura Cliente/Servidor, que se refiere a la estructura cliente y servidor.
  • Estructura B/S: el nombre completo es Estructura navegador/servidor, que se refiere a la estructura del navegador y el servidor.

Protocolo de comunicación de red

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

  • Protocolo TCP/IP: Protocolo de control de transmisión/Protocolo de Internet (Protocolo de control de transmisión/Protocolo de Internet), es
    El protocolo más básico y extendido de Internet.
    Insertar descripción de la imagen aquí

Clasificación de protocolo

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

  1. TCP: Protocolo de control de transmisión. El protocolo TCP es un protocolo de comunicación orientado a la conexión, es decir, antes de transmitir datos, se establece una conexión lógica entre el extremo emisor y el extremo receptor, y luego se transmiten los datos. Proporciona una transmisión de datos confiable y sin errores entre dos. ordenadores.
  2. UDP: Protocolo de datagramas de usuario. El protocolo UDP es un protocolo sin conexión. Al transmitir datos, no es necesario establecer una conexión, independientemente de si se inicia el servicio de la otra parte, los datos, el origen y el destino de los datos se encapsulan directamente en el paquete de datos y se envían directamente. El tamaño de cada paquete está limitado a 64k. Es un protocolo poco confiable porque no hay conexión, por lo que la velocidad de transmisión es rápida, pero los datos se pierden fácilmente.

Apretón de manos de tres vías en TCP: En el protocolo TCP, en la etapa de preparación del envío de datos, existen tres interacciones entre el cliente y el servidor para garantizar la confiabilidad de la conexión.

  • En el primer protocolo de enlace, el cliente envía una solicitud de conexión al servidor y espera la confirmación del servidor.
  • En el segundo apretón de manos, el servidor envía una respuesta al cliente, notificándole que se ha recibido la solicitud de conexión.
  • En el tercer apretón de manos, el cliente envía información de confirmación al servidor nuevamente para confirmar la conexión.

Tres elementos de la programación de redes.

  1. Protocolo: Las reglas que deben cumplir las comunicaciones de la red informática.
  2. Dirección IP: se refiere a la Dirección de Protocolo de Internet, comúnmente conocida como IP. Las direcciones IP se utilizan para numerar de forma única los dispositivos informáticos en una red.
  • IPv4: Es un número binario de 32 bits, generalmente dividido en 4 bytes, expresado en forma abcd, como 192.168.65.100. Entre ellos, a, b, cyd son todos números enteros decimales entre 0 y 255, por lo que se pueden representar hasta 4,2 mil millones.
  • Utilizando una longitud de dirección de 128 bits, cada grupo de 16 bytes se divide en 8 grupos de números hexadecimales, expresados ​​como ABCD:EF01:2345:6789:ABCD:EF01:2345:6789, lo que resuelve el problema de recursos insuficientes de direcciones de red.
    Comandos de uso común:
  • ipconfig [Ver la dirección IP local]
    Insertar descripción de la imagen aquí
  • Haga ping a la dirección IP del espacio [verifique si la red está conectada]
  1. El número de puerto
  • Un número entero representado por dos bytes, su rango de valores es 0 ~ 65535.Entre ellos, algunas redes conocidas utilizan números de puerto entre 0 y 1023.
    Servicios y aplicaciones de red; las aplicaciones normales deben utilizar números de puerto superiores a 1024. Si el número de puerto está ocupado por otro servicio o aplicación, el programa actual no podrá iniciarse.
    Identificar procesos en la red: 协议 + IP地址 + 端口号

programa de comunicación TCP

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

Pasos de comunicación

  • El programa del servidor debe iniciarse con anticipación y esperar la conexión del cliente.
  • El cliente se conecta activamente al servidor y sólo puede comunicarse si la conexión se realiza correctamente. El servidor no puede conectarse activamente con el cliente.

En Java, se proporcionan dos clases para implementar programas de comunicación TCP:

  1. Cliente: Representado por la clase java.net.Socket. Cree un objeto Socket, envíe una solicitud de conexión al servidor, el servidor responde a la solicitud y los dos establecen una conexión e inician la comunicación.
  2. Servidor: representado por la clase java.net.ServerSocket. Crear un objeto ServerSocket equivale a iniciar un servicio y esperar a que el cliente se conecte.

clase de zócalo

Socket 类:该类实现客户端套接字,套接字指的是两台设备之间通讯的端点。
Método de construcción:
public Socket(String host, int port) :Crea un objeto de socket y lo conecta al número de puerto especificado en el host especificado. Si el host especificado es nulo, equivale a que la dirección especificada sea la dirección de loopback (La dirección de loopback (127.xxx) es la dirección de loopback local (Dirección de loopback))。
Métodos de miembro:

  • public InputStream getInputStream() : Devuelve el flujo de entrada para este socket.
  • public OutputStream getOutputStream() : Devuelve el flujo de salida para este socket.
  • public void close() : cierre este enchufe.
  • public void shutdownOutput() : Desactiva el flujo de salida para este socket.

Clase ServerSocket

ServerSocket 类:这个类实现了服务器套接字,该对象等待通过网络的请求。
Método de construcción:
public ServerSocket (puerto int): utilice este constructor para vincularlo a un puntero al crear un objeto ServerSocket.
En un determinado número de puerto, el puerto del parámetro es el número de puerto.
Métodos de miembro:
public Socket accept() : Escuche y acepte conexiones y devuelva un nuevo objeto Socket para comunicarse con el cliente.este método
Se bloqueará hasta que se establezca la conexión.

Programa de red TCP simple

Análisis de comunicación TCP:

  1. [Servidor] Inicie, cree el objeto ServerSocket y espere la conexión.
  2. [Cliente] Inicie, cree un objeto Socket y solicite conexión.
  3. [Servidor] recibe la conexión, llama al método de aceptación y devuelve un objeto Socket.
  4. [Cliente] Objeto de socket, obtiene OutputStream y escribe datos en el servidor.
  5. [Servidor] Objeto Socket, obtiene el InputStream y lee los datos enviados por el cliente.
  6. [Servidor] Objeto de socket, obtiene OutputStream y escribe datos en el cliente.
  7. [Cliente] Objeto Scoket, obtiene InputStream, analiza y escribe datos.
  8. [Cliente] Liberar recursos y desconectarse.

Ejemplo de código:

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

El servidor especifica el número de puerto, obtiene el objeto Socket a través del método aceptar (), obtiene el flujo de entrada a través del objeto del cliente y finalmente lee los datos y espera el mensaje enviado por el cliente.

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

Cuando se crea el cliente, especifique la dirección IP y el número de puerto de la conexión para facilitar la conexión al servidor, obtenga el flujo de salida y los datos de salida a través del objeto Socket del cliente.
Insertar descripción de la imagen aquí

Carga de archivos [Extendido]

  1. [Cliente] Flujo de entrada, lee datos de archivos desde el disco duro al programa.
  2. [Cliente] Flujo de salida, escribe datos de archivos en el servidor.
  3. [Servidor] Flujo de entrada, lee datos de archivos en el programa del servidor.
  4. [Servidor] Flujo de salida, escribe datos de archivos en el disco duro del servidor.
  5. [Servidor] Obtenga el flujo de salida y vuelva a escribir los datos.
  6. [Cliente] Obtenga el flujo de entrada, analice y vuelva a escribir los datos.

数据准备:Coloque un archivo llamado test.jpg debajo de la unidad D y cree una carpeta de prueba

Ejemplo de código:

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

Aquí primero creamos un objeto de servidor, usamos while (true) para garantizar una conexión continua al servidor y luego iniciamos un hilo para garantizar que cuando un usuario carga un archivo grande, la eficiencia de otros usuarios que cargan archivos no se vea afectada. Utilice los milisegundos del sistema + '.jpg' para configurar el nombre del archivo y asegurarse de que el nombre del archivo no se sobrescriba debido al mismo nombre de archivo durante la carga.

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

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Aquí podemos ver que nuestro servidor guardó exitosamente el archivo enviado por el usuario al disco duro.

Los amantes de Java pueden conocer el artículo. El autor continuará actualizándolo y esperará su atención y recopilación. . .