Java avanzado: el uso de la programación de red

1. Descripción general de la programación de red

La programación de red es escribir un programa para permitir la transmisión de datos entre dos (o más) dispositivos (como computadoras) en Internet
1. Propósito: comunicar directa o indirectamente datos con otras computadoras a través de protocolos de red para comunicarse.

2. Dos problemas a tener en cuenta en la programación de red

①Si localiza con precisión uno o más hosts en la red, ubique la aplicación específica en el host

② Cómo transferir datos de manera confiable y eficiente después de encontrar el host

2. Dos elementos clave en la comunicación de la red.

Elemento 1, IP y número de puerto:

①IP: ordenador (demasiado abstracta, no es fácil de recordar) en Internet único identificador
② número de puerto: una ubicación específica en el programa de control (proceso)
③IP Categoría: IPv4 e IPv6; la diferencia LAN World Wide Web y
④ en Java La clase InetAddress representa IP.
⑤ Nombre de dominio: www.baidu.com DNS (servidor de resolución de nombres de dominio), que puede utilizarse para acceder a la IP.
⑥ Dirección de bucle local: 127.0.0.1 Correspondencia: localhost

Número de puerto:

① Los diferentes procesos tienen diferentes números de puerto

② se especifica como un entero de 16 bits 0-65535

Classification Clasificación de
puerto Puerto reconocido: 0 ~ 1023 está ocupado por una comunicación de servicio predefinida (por ejemplo: puerto 80 ocupado por HTTP)

Puerto de registro: 1024 ~ 49151 asignado a procesos o aplicaciones de usuario (por ejemplo, Tomcat ocupa el puerto 8080, MySQL ocupa el puerto 3306)

Puerto dinámico / privado: 49152 ~ 65535

④La combinación del número de puerto y la dirección IP da como resultado un socket de red: Socket

Elemento 2. Protocolo de comunicación de red: (modelo de referencia TCP / IP)

Inserte la descripción de la imagen aquí
Concepto:
debe haber algunas limitaciones para realizar la comunicación en la red informática, es decir, el protocolo de comunicación, establecer estándares para la velocidad, el código de transmisión, la estructura del código, los pasos de control de transmisión, el control de errores, etc.

Capa de protocolo de comunicación: capa de enlace físico, capa de IP, capa de transporte, capa de aplicación

Hay dos protocolos importantes en el protocolo de la capa de transporte:

① Protocolo de control de transmisión (TCP)

Protocol Protocolo de datagramas de usuario (UDP)

Protocolo TCP / IP: es un grupo de protocolos con el nombre de Protocolo de control de transmisión (TCP) y Protocolo de interconexión de red (IP), que incluye múltiples protocolos con diferentes funciones y relacionados entre sí.

La diferencia entre TCP y UDP

Protocolo TCP: (caso de vida: llamada)

1. Antes de usar el protocolo TCP, se debe establecer una conexión TCP para formar un canal de datos de transmisión
2. Antes de la transmisión, el método de "enlace de tres vías" se utiliza para la comunicación punto a punto, que es confiable 3.
Dos procesos de aplicación para la comunicación mediante el protocolo TCP : cliente, Servidor
4. Se puede transmitir una gran cantidad de datos durante la conexión
5. Una vez completada la transmisión, se debe liberar la conexión establecida, lo cual es ineficiente

Apretón de tres manos:

Inserte la descripción de la imagen aquí
El primer paso: el cliente envía una sincronización al servidor para iniciar un apretón de manos;

Paso 2: el servidor responde syn + ack al cliente después de recibir el syn;

El tercer paso: después de que el cliente recibe el syn + ack, responde al servidor con un ack que indica que recibió el syn + ack

El navegador y el servidor web remoto establecen una conexión TCP / IP a través de la negociación de protocolo de enlace TCP de tres vías. El protocolo de enlace incluye un mensaje de sincronización, un mensaje de respuesta de sincronización y un mensaje de respuesta. Estos tres mensajes se transfieren entre el navegador y el servidor. El apretón de manos primero intenta establecer la comunicación por parte del cliente, luego el servidor responde y acepta la solicitud del cliente, y finalmente el cliente envía un mensaje de que la solicitud ha sido aceptada.

El motivo del apretón de manos de tres vías: para evitar que se envíen mensajes no válidos al servidor.
Agita cuatro veces

Inserte la descripción de la imagen aquí

La primera ola de manos: una vez finalizada la transmisión de datos, el proceso de solicitud del cliente envía un segmento de liberación de conexión y deja de enviar datos. Su encabezado: FIN = 1, seq = x.

La segunda ola: después de recibir el segmento de mensaje de liberación de conexión, el servidor envía un mensaje de confirmación, cuyo encabezado es: ack = x + 1, seq = z. En este punto, la conexión ha entrado en un estado semicerrado y el cliente ya no envía datos al servidor. El servidor continuará enviando.

La tercera ola: si el servidor no tiene datos para enviar al cliente, su proceso de solicitud notifica al servidor que libere la conexión TCP.

La cuarta ola: después de que el cliente recibe el segmento de liberación de la conexión, después de 2MSL (vida máxima de finalización del mensaje), esta conexión TCP realmente ha terminado y las partes de comunicación han completado su despedida.

Protocolo UDP: (Caso de vida: Enviar SMS)

1. Encapsule los datos, el origen y el destino en paquetes de datos sin establecer una conexión

2. El tamaño de cada datagrama está limitado a 64k

3. Independientemente de si la otra parte está lista para usar, el receptor no confirma el recibo, por lo que no es confiable

4. Puede transmitir

5. No es necesario liberar recursos al final del envío de datos, la sobrecarga es pequeña y la velocidad es rápida

Cómo realizar la comunicación entre hosts en la red

1. Las direcciones de ambas partes de comunicación (IP y número de puerto)
2. Ciertas reglas (protocolo de comunicación de red)

Cómo instanciar dos métodos de InetAddress: getByName (), getLocalHost

Dos métodos comunes:
getHostName ()
getHostAddress ()

public class InetAddressTest {

    public static void main(String[] args) {

        try {
            //实例化
            //getAllByName()
            InetAddress inet = InetAddress.getByName("192.168.10.100");//  --->/192.168.10.100
            System.out.println(inet);

            InetAddress inet1 = InetAddress.getByName("www.baidu.com");//www.baidu.com/39.156.66.14
            System.out.println(inet1);

            InetAddress inet2 = InetAddress.getByName("127.0.0.1");//   /127.0.0.1
            System.out.println(inet2);

            //获取本机的IP地址
            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println(localHost);//


            //getHostName()

            //getHostAddress()



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

    }

}

En tercer lugar, la realización de la programación de red TCP.

1. El cliente envía información al servidor, y el servidor muestra los datos en la consola.

Nota: Inicie el servidor primero, luego inicie el cliente
public class TCPTest {
    /*
    客户端
     */
    @Test
    public void client(){
        Socket socket = null;
        OutputStream ops = null;
        try {
            //1.实例化对象,指明ip和端口号
            InetAddress inet = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inet,8899);

            //2.获取输出字节流,用于输出数据
            ops = socket.getOutputStream();
            //3.写出数据
            ops.write("你好,我是客户端".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源关闭
            if (ops!=null){
                try {
                    ops.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[] bytes =new byte[1024];
//        int len;
//        while ((len = is.read(bytes)) != -1){
//            String string =new String(bytes,0,len);
//            System.out.println(string);
//        }
            //4.读取输入流中的数据
            baos = new ByteArrayOutputStream();
            byte[] bytes = new byte[5];
            int len;
            while ((len = is.read(bytes)) != -1){
                baos.write(bytes,0,len);
            }
            System.out.println(baos.toString());
            //收到来自谁的数据,获取客户端的Ip地址
            System.out.println("收到了来自:"+socket.getInetAddress().getHostAddress()+"的信息");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.关闭资源
            if (baos!=null){
                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();
                }
            }
        }
    }
}

Demostración del efecto:
Inserte la descripción de la imagen aquí

2. El cliente envía el archivo al servidor y el servidor guarda el archivo localmente.

Try-catch-finally debe usarse en lugar de arroja IOException

public class TCPTest1 {

    /*
    客户端
     */
    @Test
    public void client() throws IOException {
        //1.创建socket对象,指定ip和端口号
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
        //2.获取输出流
        OutputStream os = socket.getOutputStream();
        //3.获取输入流
        FileInputStream fis = new FileInputStream(new File("IO流的分类.png"));
        //4.具体的读写过程
        byte[] bytes = new byte[1024];
        int len;
        while ((len = fis.read(bytes)) != -1){
            os.write(bytes,0,len);
        }
        //5.关闭资源
        fis.close();
        os.close();
        socket.close();

    }

    /*
    服务端
     */
    @Test
    public void server() throws IOException {
        //1.创建ServerSocket对象,指定自己的端口号
        ServerSocket ss = new ServerSocket(9090);
        //2.使用accept(),获取客户端的socket
        Socket socket = ss.accept();
        //3.获取客户端的输入流
        InputStream is = socket.getInputStream();
        //4.指明输出的位置
        FileOutputStream fos = new FileOutputStream(new File("IO流的分类2.png"));
        //5.具体的操作过程
        byte[] bytes = new byte[1024];
        int len;
        while ((len = is.read(bytes)) != -1){
            fos.write(bytes,0,len);
        }
        System.out.println("接收成功");
        //6.资源关闭
        fos.close();
        is.close();
        socket.close();
        ss.close();

    }
}

3. Envíe el archivo del cliente al servidor, el servidor lo guarda en el local y devuelve "enviado correctamente" al cliente
public class TCPTest2 {
    /*
   客户端
    */
    @Test
    public void client() throws IOException {
        //1.创建socket对象,指定ip和端口号
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
        //2.获取输出流
        OutputStream os = socket.getOutputStream();
        //3.获取输入流
        FileInputStream fis = new FileInputStream(new File("IO流的分类.png"));
        //4.具体的读写过程
        byte[] bytes = new byte[1024];
        int len;
        while ((len = fis.read(bytes)) != -1){
            os.write(bytes,0,len);
        }

        //关闭数据的输出,服务器就会得到明确的指示,如果没有shutdownOutput(),就会被read()阻塞,执行不了下面的操作
        socket.shutdownOutput();

        //5.接收来自于服务端的数据,并显示到控制台上
        InputStream is = socket.getInputStream();

        //为了不乱码,使用ByteArrayOutputStream
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] bytes1 = new byte[5];
        int len1;
        while ((len1 = is.read(bytes1)) != -1){
             baos.write(bytes1,0,len1);
        }
        //显示数据
        System.out.println(baos.toString());

        //6.关闭资源
        fis.close();
        os.close();
        socket.close();
        baos.close();

    }

    /*
    服务端
     */
    @Test
    public void server() throws IOException {
        //1.创建ServerSocket对象,指定自己的端口号
        ServerSocket ss = new ServerSocket(9090);
        //2.使用accept(),获取客户端的socket
        Socket socket = ss.accept();
        //3.获取客户端的输入流
        InputStream is = socket.getInputStream();
        //4.指明输出的位置
        FileOutputStream fos = new FileOutputStream(new File("IO流的分类4.png"));
        //5.具体的操作过程
        byte[] bytes = new byte[1024];
        int len;
        //read()为阻塞式方法,一直停留在循环中
        while ((len = is.read(bytes)) != -1){
            fos.write(bytes,0,len);
        }
        //6.服务端给客户端反馈
        System.out.println("发送成功!");

        OutputStream os = socket.getOutputStream();
        os.write("数据发送成功".getBytes());

        //7.资源关闭
        fos.close();
        is.close();
        socket.close();
        ss.close();
        os.close();

    }
}

Cuatro, programación de red de protocolo UDP


    /*
    发送端
     */
    @Test
    public void sender() throws IOException {
        //1.实例化DatagramSocket
        DatagramSocket socket = new DatagramSocket();

        //2.数据的声明
        String str = "UDP的网络编程";
        //3.转换为字节数组
        byte[] data = str.getBytes();

        //4.指定ip
        InetAddress inet = InetAddress.getLocalHost();

        //5.实例化DatagramPacket(数据报)
        DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);

        //6.发送数据报
        socket.send(packet);

        //7.关闭资源
        socket.close();

    }
    /*
    接收端
     */
    @Test
    public void  receiver() throws IOException {
        //1.实例化DatagramSocket,指定自己的端口号,确定自己的进程
        DatagramSocket socket = new DatagramSocket(9090);

        //2.数据封装在DatagramPacket,不再发送,不用指定端口号和ip
        byte[] bytes = new byte[100];
        DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);

        //3.接收数据
        socket.receive(packet);
        //4.输出数据
        //packet.getData()获取packet中的数据,从0开始,到哪里结束
        System.out.println(new String(packet.getData(),0,packet.getLength()));

        //5.资源关闭
        socket.close();
    }

Cinco, programación de red URL

1. URL (Localizador uniforme de recursos): Localizador uniforme de recursos, que representa la dirección de un recurso en Internet

2. La estructura básica de la URL consta de cinco partes:

<Protocolo de transporte>: // <nombre de host>: <número de puerto> / <nombre de archivo> # ¿Nombre de clip? Lista de parámetros
Ejemplo: http://192.168.1.100:8080/helloworld/index.jsp? nombre de usuario = admin & contraseña = 123456

3. Métodos comunes:
public String getProtocol (): obtiene el nombre del protocolo de la URL

public String getHost (): obtiene el nombre de host de la URL

public String getPort (): obtiene el número de puerto de la URL

public String getPath (): obtiene la ruta del archivo de la URL

public String getFile (): obtiene el nombre del archivo de la URL

public String getQuery (): obtiene el nombre de la consulta de la URL

public class URLTest {
    public static void main(String[] args) {
        try {
            URL url = new URL("http://192.168.1.100:8080/helloworld/index.jsp?username=admin&password=123456");

            System.out.println(url.getProtocol());
            System.out.println(url.getHost());
            System.out.println(url.getPort());
            System.out.println(url.getPath());
            System.out.println(url.getFile());
            System.out.println(url.getQuery());



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

Use la programación de red URL para descargar archivos en Tomcat
public class URLTest1 {
    public static void main(String[] args) {
        HttpURLConnection urlConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            //下载Tomcat服务器中的数据,需要开启Tomcat服务器
            URL url =new URL("http://192.168.1.100:8080/helloworld/IO流的分类.png");

            //找到连接对象
            urlConnection = (HttpURLConnection) url.openConnection();

            //获取连接,访问服务器
            urlConnection.connect();

            //得到一个输入流
            is = urlConnection.getInputStream();

            //将从服务器得到的数据,写入到具体的文件中,再main方法中,会写入到当前工程下
            fos = new FileOutputStream("IO流的分类5.png");

            //读写过程
            byte[] bytes = new byte[1024];
            int len;
            //读取文件
            while ((len = is.read(bytes)) != -1){
                //写入到文件中
                fos.write(bytes,0,len);
            }
            System.out.println("下载完成!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (urlConnection != null){
                //断开连接
                urlConnection.disconnect();
            }
        }
    }
}

Publicado 19 artículos originales · elogiado 0 · visitas 475

Supongo que te gusta

Origin blog.csdn.net/weixin_43244120/article/details/105621397
Recomendado
Clasificación