Compartilhamento de tecnologia

Java Advanced Key Knowledge Points-23-Programação de rede

2024-07-12

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

Introdução à programação de rede

estrutura de software

  • Estrutura C/S: O nome completo é estrutura Cliente/Servidor, que se refere à estrutura cliente e servidor.
  • Estrutura B/S: O nome completo é estrutura Navegador/Servidor, que se refere à estrutura do navegador e do servidor.

Protocolo de comunicação de rede

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

  • Protocolo TCP/IP: Protocolo de Controle de Transmissão/Protocolo de Internet (Protocolo de Controle de Transmissão/Protocolo de Internet), é
    O protocolo mais básico e difundido da Internet.
    Insira a descrição da imagem aqui

Classificação do protocolo

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

  1. TCP: Protocolo de Controle de Transmissão. O protocolo TCP é um protocolo de comunicação orientado à conexão, ou seja, antes de transmitir os dados, uma conexão lógica é estabelecida entre o terminal emissor e o terminal receptor e, em seguida, os dados são transmitidos. computadores.
  2. UDP: Protocolo de Datagrama do Usuário. O protocolo UDP é um protocolo sem conexão. Ao transmitir dados, não há necessidade de estabelecer uma conexão. Independentemente de o serviço da outra parte ser iniciado, os dados, a fonte e o destino dos dados são encapsulados diretamente no pacote de dados e enviados diretamente. O tamanho de cada pacote é limitado a 64k. É um protocolo não confiável porque não há conexão, então a velocidade de transmissão é rápida, mas os dados são facilmente perdidos.

Handshake de três vias em TCP: No protocolo TCP, na fase de preparação para envio de dados, existem três interações entre o cliente e o servidor para garantir a confiabilidade da conexão.

  • No primeiro handshake, o cliente envia uma solicitação de conexão ao servidor e aguarda a confirmação do servidor.
  • No segundo handshake, o servidor envia uma resposta de volta ao cliente, notificando-o de que a solicitação de conexão foi recebida.
  • No terceiro handshake, o cliente envia novamente informações de confirmação ao servidor para confirmar a conexão.

Três elementos de programação de rede

  1. Protocolo: As regras que as comunicações em rede de computadores devem obedecer
  2. Endereço IP: refere-se ao endereço de protocolo da Internet, comumente conhecido como IP. Os endereços IP são usados ​​para numerar exclusivamente dispositivos de computador em uma rede.
  • IPv4: É um número binário de 32 bits, geralmente dividido em 4 bytes, expresso na forma de abcd, como 192.168.65.100. Entre eles, a, b, c e d são todos números inteiros decimais entre 0 e 255, portanto, até 4,2 bilhões podem ser representados.
  • Usando um comprimento de endereço de 128 bits, cada grupo de 16 bytes é dividido em 8 grupos de números hexadecimais, expressos como ABCD:EF01:2345:6789:ABCD:EF01:2345:6789, o que resolve o problema de recursos insuficientes de endereço de rede. .
    Comandos comumente usados:
  • ipconfig [Ver o endereço IP local]
    Insira a descrição da imagem aqui
  • Faça ping no endereço IP do espaço [verifique se a rede está conectada]
  1. O número da porta
  • Um número inteiro representado por dois bytes, seu intervalo de valores é de 0 a 65535.Entre eles, números de porta entre 0 e 1023 são usados ​​por algumas redes conhecidas
    Serviços e aplicativos de rede, aplicativos comuns precisam usar números de porta acima de 1024. Se o número da porta estiver ocupado por outro serviço ou aplicativo, o programa atual não será iniciado.
    Identifique processos na rede: 协议 + IP地址 + 端口号

Programa de comunicação TCP

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

Etapas de comunicação

  • O programa servidor precisa ser iniciado com antecedência e aguarda a conexão do cliente.
  • O cliente se conecta ativamente ao servidor e só pode se comunicar se a conexão for bem-sucedida. O servidor não pode conectar-se ativamente ao cliente.

Em Java, duas classes são fornecidas para implementar programas de comunicação TCP:

  1. Cliente: Representado pela classe java.net.Socket. Crie um objeto Socket, envie uma solicitação de conexão ao servidor, o servidor responde à solicitação e os dois estabelecem uma conexão e iniciam a comunicação.
  2. Servidor: representado pela classe java.net.ServerSocket. Criar um objeto ServerSocket equivale a iniciar um serviço e aguardar a conexão do cliente.

Classe de soquete

Socket 类:该类实现客户端套接字,套接字指的是两台设备之间通讯的端点。
Método de construção:
public Socket(String host, int port) :Cria um objeto de soquete e o conecta ao número de porta especificado no host especificado. Se o host especificado for nulo, será equivalente ao endereço especificado ser o endereço de loopback (O endereço de loopback (127.xxx) é o endereço de loopback local (endereço de loopback))。
Métodos de membros:

  • public InputStream getInputStream() : Retorna o fluxo de entrada para este soquete.
  • public OutputStream getOutputStream() : Retorna o fluxo de saída para este soquete.
  • public void close() : Feche este soquete.
  • public void shutdownOutput() : desativa o fluxo de saída para este soquete.

Classe ServerSocket

ServerSocket 类:这个类实现了服务器套接字,该对象等待通过网络的请求。
Método de construção:
public ServerSocket (int port): Use este construtor para vinculá-lo a um ponteiro ao criar um objeto ServerSocket.
Em um determinado número de porta, o parâmetro port é o número da porta.
Métodos de membros:
public Socket accept() : escuta e aceita conexões e retorna um novo objeto Socket para comunicação com o cliente.este método
Irá bloquear até que a conexão seja estabelecida.

Programa de rede TCP simples

Análise de comunicação TCP:

  1. [Servidor] Inicie, crie o objeto ServerSocket e aguarde a conexão.
  2. [Cliente] Inicie, crie o objeto Socket e solicite a conexão.
  3. [Servidor] recebe a conexão, chama o método accept e retorna um objeto Socket.
  4. [Cliente] Objeto Socket, obtém OutputStream e grava dados no servidor.
  5. [Servidor] Objeto Socket, obtém o InputStream e lê os dados enviados pelo cliente.
  6. [Servidor] Objeto Socket, obtém OutputStream e grava os dados de volta no cliente.
  7. [Cliente] Objeto Scoket, obtém InputStream, analisa e grava dados.
  8. [Cliente] Libere recursos e desconecte.

Exemplo de código:

  • Terminal de serviço:
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

O servidor especifica o número da porta, obtém o objeto Socket através do método accept(), obtém o fluxo de entrada através do objeto cliente e, finalmente, lê os dados e aguarda a mensagem enviada pelo 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

Quando o cliente for criado, especifique o endereço IP e o número da porta da conexão para facilitar a conexão com o servidor, obtenha o fluxo de saída e os dados de saída por meio do objeto Socket do cliente.
Insira a descrição da imagem aqui

Upload de arquivo [estendido]

  1. [Cliente] Fluxo de entrada, lê os dados do arquivo do disco rígido para o programa.
  2. [Cliente] Fluxo de saída, grava dados do arquivo no servidor.
  3. [Servidor] Fluxo de entrada, lê os dados do arquivo para o programa do servidor.
  4. [Servidor] Fluxo de saída, grava dados do arquivo no disco rígido do servidor.
  5. [Servidor] Obtenha o fluxo de saída e grave os dados.
  6. [Cliente] Obtenha o fluxo de entrada, analise e grave os dados.

数据准备:Coloque um arquivo chamado test.jpg na unidade D e crie uma pasta de teste

Exemplo 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

Aqui, primeiro criamos um objeto de servidor, usamos while(true) para garantir a conexão contínua com o servidor e, em seguida, iniciamos um thread para garantir que quando um usuário carrega um arquivo grande, a eficiência de outros usuários que carregam arquivos não será afetada. Use os milissegundos do sistema + '.jpg' para definir o nome do arquivo para garantir que o nome do arquivo não seja substituído devido ao mesmo nome de arquivo durante o upload.

  • 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

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
Aqui podemos ver que nosso servidor salvou com sucesso o arquivo enviado pelo usuário para o disco rígido.

Os amantes de Java são bem-vindos para aprender sobre o artigo. O autor continuará a atualizá-lo e aguardará sua atenção e coleção. . .