Resumo de aprendizagem Java (edição 2021) --- princípios básicos de programação de rede

I. Visão geral

  • O objetivo da programação de rede: direta ou indiretamente realizar a troca de dados e comunicação com outros computadores através de protocolos de rede

  • Dois problemas precisam ser resolvidos para realizar a comunicação de rede:

    • Como localizar com precisão um ou mais hosts na rede; localizar aplicativos específicos no host
    • Depois de encontrar o hospedeiroComo transferir dados de maneira confiável e eficiente

Dois: Elementos de Comunicação de Rede

  • Resolva o problema um: IP e número da porta
  • Resolva o segundo problema: Forneça protocolo de comunicação de rede: modelo de referência TCP / IP (camada de aplicação, camada de transporte, camada de rede, camada física + de enlace de dados)

Elemento de comunicação 1: IP e número da porta

Compreensão de IP

  • IP : identifica exclusivamente o computador (entidade de comunicação) na Internet
  • Use a classe InetAddress para representar IP em Java
  • Classificação IP :
    • Método 1: IPv4 e IPv6
    • Método 2: endereço público (usado pela World Wide Web) e endereço privado (usado pela rede local)
  • Nome de domínio : resolva o nome de domínio para um endereço IP por meio de um servidor de resolução de nome de domínio www.baidu.com www.mi.com www.jd.com
  • Resolução do nome de domínio : O nome de domínio é fácil de lembrar. Quando o nome de domínio de um host é inserido ao se conectar à rede, o servidor de nome de domínio (DNS) é responsável por converter o nome de domínio em um endereço IP, a fim de estabelecer uma conexão com o host.
  • Endereço de loopback local (hostAddress) : 127.0.0.1 Nome do host (hostName): localhost
  • Existem duas maneiras de os hosts na Internet expressarem endereços:
    • Nome da região (hostName): www.baidu.com
    • Endereço IP (hostAddress): 202.108.35.210

O número da porta:
Insira a descrição da imagem aqui

Classe InetAddress
Insira a descrição da imagem aqui

  • O nome de domínio é fácil de lembrar. Após inserir o nome de domínio de um host ao se conectar à rede, o servidor de nome de domínio (DNS)
    é responsável por converter o nome de domínio em um endereço IP, para que a conexão possa ser estabelecida com o hospedeiro. ------- DNS

Insira a descrição da imagem aqui

  • formas comumente usadas

Insira a descrição da imagem aqui
Exemplo de código:

public static void main(String[] args) {
    
    
    try {
    
    
        //通过域名来获得InetAddress实例
        InetAddress inet2 = InetAddress.getByName("www.baidu.com");
        System.out.println(inet2);//www.baidu.com/39.156.66.18
     
        //通过ip来获得InetAddress实例
        InetAddress inet3 = InetAddress.getByName("127.0.0.1");
        System.out.println(inet3);//127.0.0.1
     
        //获取本地InetAddress实例
        InetAddress inet4 = InetAddress.getLocalHost();
        System.out.println(inet4);//DESKTOP-EV2S7MJ/10.1.1.127

        //getHostAddress()获取主机域名
        System.out.println(inet2.getHostName());//www.baidu.com
        //getHostAddress();获取主机的ip地址
        System.out.println(inet2.getHostAddress());//39.156.66.14
    } catch (UnknownHostException e) {
    
    
        e.printStackTrace();
    }
}

Elemento de comunicação dois: protocolo de comunicação de rede

Protocolo TCP e protocolo UDP

Insira a descrição da imagem aqui

  • Handshake de três vias: certifique-se de que o parceiro de comunicação esteja online
  • Handshake de quatro vias: certifique-se de que a conexão seja interrompida

Soquete
Insira a descrição da imagem aqui

  • Construtores comumente usados ​​da classe Socket:

    • soquete público (Endereço InetAddress, porta interna) Para criar um soquete de fluxo e conectá-lo ao número de porta especificado do endereço IP especificado.
    • soquete público (Host de string, porta int) Para criar um soquete de fluxo e conectá-lo ao host designado especificado no número da porta.
  • Métodos comuns da classe Socket:

Insira a descrição da imagem aqui

Três: programação de rede TCP

1: Breve descrição

A programação de soquetes baseada na linguagem Java é dividida em cliente e servidor

2: O processo de trabalho do cliente Socket inclui as seguintes quatro etapas básicas:

Insira a descrição da imagem aqui

  • Nota: O programa cliente pode usar a classe Socket para criar objetos,Ao mesmo tempo, criado irá conectar-se automaticamente ao lado do servidor para iniciar o
    contato

3: O processo de trabalho do programa do servidor inclui as seguintes quatro etapas básicas:
Insira a descrição da imagem aqui
4: Exemplo:

Insira a descrição da imagem aqui

Exemplo de código 1: ----- O cliente envia informações ao servidor e o servidor exibe os dados no console

import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;

/**
 * 实现TCP的网络编程
 * 例子1:客户端发送信息给服务端,服务端将数据显示在控制台上
 */
public class TCPTest1 {
    
    

    //客户端
    @Test
    public void client()  {
    
    
        Socket socket = null;
        OutputStream os = null;
        try {
    
    
            //1.创建Socket对象,指明服务器端的ip和端口号
            InetAddress inet = InetAddress.getByName("192.168.14.100");//获取此IP地址的主机名
            socket = new Socket(inet,8899);
            //2.获取一个输出流,用于发送数据给服务器
            os = socket.getOutputStream();
            //3.写出数据的操作
            os.write("你好,我是客户端mm".getBytes());
            
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //4.资源的关闭
            if(os != null){
    
    
                try {
    
    
                    os.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
            if(socket != null){
    
    
                try {
    
    
                    socket.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }

            }
        }



    }
    //服务端
    @Test
    public void server()  {
    
    

        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
    
    
            //1.创建服务器端的ServerSocket,指明自己的端口号
            ss = new ServerSocket(8899);
            //2.调用accept()表示接收来自于客户端的socket(监听一个客户端的连接)
            //该方法是一个阻塞方法,如果没有客户端连接将一直等待
            socket = ss.accept();
            //3.获取输入流,用来接收客户端发送的数据
            is = socket.getInputStream();

            //不建议这样写,可能会有乱码
//        byte[] buffer = new byte[1024];因为此处长度如果小于接受数据的长度,导致分成两半,后续用String接收会乱码
//        int len;
//        while((len = is.read(buffer)) != -1){
    
    
//            String str = new String(buffer,0,len);
//            System.out.print(str);
//        }
            
            //4.读取输入流中的数据
            //因为此处如果小于接收的数据长度,并不会单独还原成字符串,而是先拼起来整体再还原
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[5];
            int len;
            while((len = is.read(buffer)) != -1){
    
    
            	/**ByteArrayOutputStream源码
            	 * public synchronized void write(byte b[], int off, int len) {
        				Objects.checkFromIndexSize(off, len, b.length);
        				ensureCapacity(count + len);
        				System.arraycopy(b, off, buf, count, len);
        				count += len;
    				}
            	 */
            	//把数据写到baos对象,以便后续整体还原
                baos.write(buffer,0,len);
            }
            /**ByteArrayOutputStream源码
             * protected byte buf[];
             */
            
            /**
             * public synchronized String toString() {
        		return new String(buf, 0, count);
    		}
             */
            		//把内部字节字符直接转换成字符串
            System.out.println(baos.toString());

            System.out.println("收到了来自于:" + socket.getInetAddress().getHostAddress() + "的数据");

        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if(baos != null){
    
    
                //5.关闭资源
                try {
    
    
                    baos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(is != null){
    
    
                try {
    
    
                    is.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(socket != null){
    
    
                try {
    
    
                    socket.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(ss != null){
    
    
                try {
    
    
                    ss.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }

        }





    }

}

Exemplo de código 2: ----- Envie um arquivo do cliente para o servidor, e o servidor o salva localmente. E retornar "enviar com sucesso" para o cliente


/*
    这里涉及到的异常,应该使用try-catch-finally处理
     */

public class TCPTest3 {
    
    
    @Test//客户端
    public void client() throws Exception{
    
    
        //创建Socket对象,指明服务器端的ip和端口号
        InetAddress inet = InetAddress.getByName("127.0.0.1");
        Socket socket = new Socket(inet,9090);
      
        //获取输出流,用来发送数据给服务器
        OutputStream so = socket.getOutputStream();
        FileInputStream fis = new FileInputStream(new File("one.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        //将从文件中读取的数据发送给服务器
        while((len = fis.read(buffer)) != -1){
    
    
            so.write(buffer,0,len);
        }
        //关闭数据的输出,会在流末尾写入一个“流的末尾”的标记,服务器才能读到-1,否则对方的读取会一直阻塞
        socket.shutdownOutput();
      
        //接收来自服务器端的数据,并显示到控制台上
        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        System.out.println("我想接收来自服务器的数据");
        while((len = is.read(buffer)) != -1){
    
    
            baos.write(buffer,0,len);
        }
        System.out.println(baos.toString());
        //关闭流
        baos.close();
        is.close();
        fis.close();
        so.close();
        socket.close();
    }

    @Test//服务器
    public void server() throws Exception{
    
    
        ServerSocket ss = new ServerSocket(9090);
        Socket socket = ss.accept();
        InputStream is = socket.getInputStream();
        FileOutputStream fos = new FileOutputStream(new File("three.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
    
    
            fos.write(buffer,0,len);
        }
        //服务器端给与客户端反馈
        OutputStream os = socket.getOutputStream();
        os.write("你好,文件我已经收到".getBytes());
        //关闭流
        os.close();
        fos.close();
        is.close();
        socket.close();
        ss.close();
    }
}

Quatro: programação de rede UDP (entender)

Cinco: programação de URL - representa o endereço de um determinado recurso na Internet

Insira a descrição da imagem aqui

Visão geral:
Insira a descrição da imagem aqui
a estrutura básica do URL consiste em 5 partes:
Insira a descrição da imagem aqui
Métodos comuns de classe de URL:

Insira a descrição da imagem aqui
Exemplo de código:

public class URLTest {
    
    

    public static void main(String[] args) {
    
    

        try {
    
    

            URL url = new URL("http://localhost:8080/examples/beauty.jpg?username=Tom");

//            public String getProtocol(  )     获取该URL的协议名
            System.out.println(url.getProtocol());
//            public String getHost(  )           获取该URL的主机名
            System.out.println(url.getHost());
//            public String getPort(  )            获取该URL的端口号
            System.out.println(url.getPort());
//            public String getPath(  )           获取该URL的文件路径
            System.out.println(url.getPath());
//            public String getFile(  )             获取该URL的文件名
            System.out.println(url.getFile());
//            public String getQuery(   )        获取该URL的查询名
            System.out.println(url.getQuery());




        } catch (MalformedURLException e) {
    
    
            e.printStackTrace();
        }

    }


}

Acho que você gosta

Origin blog.csdn.net/m0_51755061/article/details/114269658
Recomendado
Clasificación