Conocimientos relacionados con la programación en red Java

Algunos conocimientos básicos de la red.

Clasificación de direcciones IP

Las direcciones IP se dividen en 5 tipos según la ID de red, la dirección de tipo A, la dirección de tipo B, la dirección de tipo C, la dirección de tipo D y la dirección de tipo E. La clase A está reservada para agencias gubernamentales, la clase B se asigna a empresas medianas, la clase C se asigna a cualquier persona que lo necesite, la clase D se usa para multidifusión y la clase E se usa para experimentos. El número de direcciones que se pueden acomodar en cada tipo es diferente. (La dirección IP consta del número de red y el número de host).

  • Dirección de clase A

    Una dirección IP de clase A consta de una dirección de red de 1 byte y una dirección de host de 3 bytes. El bit más alto de la dirección de red debe ser "0", y el rango de direcciones es de 1.0.0.0 a 126.0.0.0. Hay 126 redes de Clase A disponibles, y cada red puede acomodar más de 100 millones de hosts. Las direcciones de clase A generalmente se asignan a redes grandes.

  1. El primer byte de la dirección de clase A es la dirección de red, los otros 3 bytes son la dirección de host y la máscara de subred predeterminada es 255.0.0.0.
  2. Rango de direcciones de clase A: 0.0.0.0—126.255.255.255 (0.0.0.0 y 126.255.255.255 generalmente no se usan).
  3. Direcciones privadas y direcciones reservadas en direcciones de clase A.
  4. 10.XXX es una dirección privada (una llamada dirección privada es una dirección que no se usa en Internet sino que se usa en una red de área local).
  5. 127.XXX es una dirección reservada, utilizada para la prueba de bucle.
  • Dirección de clase B

    Una dirección IP de clase B consta de una dirección de red de 2 bytes y una dirección de host de 2 bytes. El bit más alto de la dirección de red debe ser "10", y el rango de direcciones es de 128.0.0.0 a 191.255.255.255. Hay 16,382 redes de Clase B disponibles, y cada red puede acomodar más de 60,000 hosts, generalmente asignados a redes de tamaño mediano.

  1. El primer byte y el segundo byte de la dirección de clase B son direcciones de red, los otros dos bytes son direcciones de host y la máscara de subred predeterminada es 255.255.0.0.
  2. Rango de direcciones de clase B: 128.0.0.0—191.255.255.255 (128.0.0.0 y 191.255.255.255 generalmente no se usan).
  3. Direcciones privadas y direcciones reservadas de direcciones de clase B.
  4. 172.16.0.0—172.31.255.255 es una dirección privada.
  5. 169.254.XX es la dirección reservada. Si su dirección IP se obtiene automáticamente y no encuentra un servidor DHCP disponible en la red. Obtendrá uno de los IP.
  • Dirección de clase C

    Una dirección IP de tipo C consta de una dirección de red de 3 bytes y una dirección de host de 1 byte. El bit más alto de la dirección de red debe ser "110". El rango es de 192.0.0.0 a 223.255.255.255. Las redes de clase C pueden alcanzar más de 2.09 millones, y cada red puede acomodar 254 hosts.

  1. Los primeros 3 bytes de la dirección de clase C son la dirección de red, y el cuarto byte es la dirección de host. Además, los primeros tres bits del primer byte están fijados en 110, y la máscara de subred predeterminada es 255.255.255.0.
  2. Rango de direcciones de clase C: 192.0.0.0-223.255.255.255 (192.0.0.0 y 223.255.255.255 generalmente no se usan).
  3. Dirección privada en direcciones de clase C.
  4. 192.168.XX es una dirección privada.
  • Dirección de clase D

    El primer byte de la dirección IP de clase D comienza con "1110", que es una dirección especialmente reservada. No apunta a una red específica, y este tipo de dirección se usa actualmente en Multicast. La dirección de multidifusión se usa para dirigirse a un grupo de computadoras a la vez e identifica un grupo de computadoras que comparten el mismo protocolo.

  1. Las direcciones de clase D no distinguen entre direcciones de red y direcciones de host, y los primeros cuatro bits de su primer byte se fijan en 1110.
  2. Rango de direcciones de clase D: 224.0.0.1-239.255.255.254.
  • Dirección de clase E

    Comience con "11110" y reserve para uso futuro. Todas las direcciones cero ("0.0.0.0") corresponden al host actual. La dirección IP de todos los "1" ("255.255.255.255") es la dirección de difusión de la subred actual.

  1. Las direcciones de clase E tampoco distinguen entre direcciones de red y direcciones de host. Los primeros cinco bits de su primer byte se fijan en 11110.
  2. Rango de direcciones de clase E: 240.0.0.1-255.255.255.254

Clasificación de puertos

  • Puerto conocido (puerto conocido): de 0 a 1023, están estrechamente vinculados a algunos servicios específicos. Por ejemplo, el puerto 80 está vinculado al servicio http, el puerto 443 está vinculado al servicio https, el puerto 22 está vinculado al servicio ssh, etc.
  • Puerto grueso principal (puerto registrado): 1024 a 49151, están vinculados libremente a algunos servicios, y las aplicaciones que escribimos deberían usar puertos en este rango;
  • Puertos dinámicos o privados: 49152 a 65535, estos puertos serán utilizados dinámicamente por la aplicación.

Soporte de red básico de Java

La mayoría de los tipos de soporte de red en Java están bajo el paquete java.net. Las clases de uso común son URL, URLConnection, URLDecoder, URLENcoder e InetAddress.

Uso de InetAddress

InetAddress significa dirección IP, tiene dos subclases Inet4Address e Inet6Address.

public class InetAddressDemo {

    public static void main(String[] args) throws Exception {
        //获取本机的IP地址
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println("host address:"+localHost.getHostAddress());
        System.out.println("host name:"+localHost.getHostName());
        //根据百度的域名,随机获取百度的一个IP地址
        InetAddress baidu = InetAddress.getByName("www.baidu.com");
        System.out.println("host address:"+baidu.getHostAddress());
        System.out.println("host name:"+baidu.getHostName());
        //根据IP地址,货期InetAddress
        InetAddress loopAddress = InetAddress.getByAddress(new byte[]{127,0,0,1});
        System.out.println("host address:"+loopAddress.getHostAddress());
        System.out.println("host name:"+loopAddress.getHostName());
        //根据域名,获取域名对应的所有IP地址
        InetAddress[] baidus = InetAddress.getAllByName("www.baidu.com");
        for (InetAddress inetAddress : baidus) {
            System.out.println("host address:"+inetAddress.getHostAddress());
            System.out.println("host name:"+inetAddress.getHostName());
        }
    }
}

Uso de URLEncoder y URLDecoder

Cuando la dirección URL contiene una cadena de caracteres no europeos occidentales, el sistema codificará automáticamente estos caracteres no europeos occidentales. En nuestro proceso de programación, implicará la conversión entre estas cadenas ordinarias y cadenas especiales, luego deberá usar URLEncoder y URLDecoder.

 String encodedUrl = "https://www.baidu.com/s?wd=ip%E5%9C%B0%E5%9D%80%E5%88%86%E7%B1%BB&rsv_spt=1&rsv_iqid=0xe6273c5300071242&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&oq=IP%25E5%259C%25B0%25E5%259D%2580%25E5%2588%2586%25E7%25B1%25BB&rsv_t=8798Pr4JiDoBuHX8kSW6i384TlOk5p8vEQ4c4tWrc0suF31CjvBh6stq0gyq0PtETa9x&inputT=9569&rsv_sug3=24&rsv_sug1=14&rsv_sug7=100&rsv_pq=b3c08c4200035639&bs=IP%E5%9C%B0%E5%9D%80%E5%88%86%E7%B1%BB";
String decodeURL = URLDecoder.decode(encodedUrl, Charset.forName("UTF8").name());
System.out.println("decodeURL:"+decodeURL);

Las dos clases URLEncoder y URLDecoder solo proporcionan métodos de codificación y decodificación para nuestro uso.

Uso de URL, URLConnection y URLPermission

Aquí está la diferencia entre URL y URI:

URI: identificador de recurso uniforme, identificador de recurso uniforme, utilizado para identificar un recurso de forma exclusiva. Cada recurso disponible en la Web, como documentos HTML, imágenes, videoclips, programas, etc., es un URI para localizar. Un URI generalmente se compone de tres partes: ① mecanismo de nombre para acceder a los recursos ② nombre de host para almacenar recursos ③ nombre de los recursos mismos , Representado por el camino, con énfasis en los recursos.

La URL es un localizador uniforme de recursos, un localizador uniforme de recursos. Es un URI específico, es decir, la URL se puede utilizar para identificar un recurso y también indica cómo ubicar el recurso. La URL generalmente consta de tres partes: ① protocolo (o llamado modo de servicio) ② la dirección IP del host (a veces incluido el número de puerto) donde se almacena el recurso ③ la dirección específica del recurso del host .

En pocas palabras, URI es un identificador único de un recurso en Internet (podemos considerarlo como la identificación de un recurso), la URL es un URI especial, la URL no solo puede identificar un recurso de Internet, sino que también se puede obtener a través de la URL Este recurso Dos tipos de URI y URL en Java corresponden a estos dos conceptos respectivamente. La clase URL puede abrir una secuencia para obtener recursos específicos.

String[] urls = {"https://img0.pconline.com.cn/pconline/1707/21/9625301_20150814_6d20f056ee9803d9419buyemaASeB0KJ_thumb.jpg"};

        for (String url : urls) {
            URL url1 = new URL(url);
            int port = url1.getPort();
            System.out.println("port:"+port);
            String host = url1.getHost();
            System.out.println("host:"+host);
            String protocol = url1.getProtocol();
            System.out.println("protocol:"+protocol);
            String file = url1.getFile();
            System.out.println("fileName:"+file);
            //这段是否要设置权限,为什么open总是失败?
            InputStream inputStream = url1.openStream();
            FileOutputStream fos = new FileOutputStream("D:\\"+new Date()+".jpeg");
            FileCopyUtils.copy(inputStream,fos);
            inputStream.close();
            fos.close();
        }

Programación de red basada en protocolo TCP

Use ServerSocket para establecer el servidor TCP

La clase que puede recibir solicitudes de otras entidades de comunicación en Java es ServerSocket. Este objeto puede escuchar conexiones de Socket desde el cliente (dos sockets para cada conexión TCP, una IP más un puerto para formar un Socket). Si no hay conexión, siempre estará en estado de espera.

  • Socket accept (): este método devuelve el Socket del cliente, ninguna conexión siempre estará en estado de espera (sincronización) y el subproceso está bloqueado (bloqueo);

ServerSocket tiene los siguientes constructores:

  • ServerSocket público (puerto int): puerto designado, valor predeterminado de trabajo atrasado 50;
  • ServerSocket público (int port, int backlog): el backlog se usa para especificar la longitud de la cola de conexión, este valor también está relacionado con el sistema operativo, intentado configurar hasta 200 en Windows, si establecemos que el valor excede 200, tomamos 200.
  • ServerSocket público (int port, int backlog, InetAddress bindAddr): si la máquina tiene varias tarjetas de red, también puede especificar qué tarjeta de red supervisar.

(Explicación detallada del comando netstat)

Use Socket para comunicación

La siguiente es una lista de clientSocket y serverSocket que son muy simples: el cliente envía un mensaje al servidor cada segundo, y el servidor da una respuesta:

Socket clientSocket = new Socket("127.0.0.1",30000);
//inputStream用来接受服务端返回的消息
InputStream inputStream = clientSocket.getInputStream();
//outputStream用来给服务端发消息
OutputStream outputStream = clientSocket.getOutputStream();
while (true){
    outputStream.write(("hi, l am clinetSocket").getBytes());
    byte[] bytes = new byte[1024];
    inputStream.read(bytes);
    System.out.println("get message from server:"+new String(bytes));
    Thread.sleep(1000);
}

Programa servidor

public class ServerSocketDemo {

    private static ExecutorService executorService = Executors.newFixedThreadPool(10);
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(30000, 5);
        while (true) {
            Socket socket = serverSocket.accept();
            System.out.println("get socket:" + socket);
            executorService.execute(new Printer(socket));
        }
    }

    private static class Printer implements Runnable {

        private Socket socket;

        public Printer(Socket socket) {
            this.socket = socket;
        }
        @Override
        public void run() {
            OutputStream outputStream;
            InputStream inputStream;
            try {
                //对于服务端来说,inputStream用来接收客户端的报文
                inputStream = socket.getInputStream();
                //对于服务端来说,outputStream用来给客户端响应报文
                outputStream = socket.getOutputStream();
                while (true) {
                    byte[] bytes = new byte[1024];
                    inputStream.read(bytes);
                    System.out.println("wa.. l got you " + new String(bytes));
                    outputStream.write("l am serverSocket".getBytes());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Zócalo medio cerrado

Un zócalo semicerrado se refiere solo al cierre de los flujos de entrada y salida del zócalo, pero no al cierre de toda la conexión del zócalo.

Uso de NIO para realizar comunicaciones de socket sin bloqueo

Una breve descripción de varias clases utilizadas para la comunicación de socket en Java NIO:

  • Selector: es un multiplexor del objeto SelectableChannel. Todos los canales que deseen comunicarse sin bloqueo deben registrarse en el objeto Selector. Puede llamar a selector = Selector.open () para construir el objeto Selector.
  • SelectionKey: una instancia de Selector tiene tres conjuntos SelectionKey. El primer tipo es todas las colecciones SelectionKey devueltas por el método de las teclas del selector (), que representan todos los canales registrados en esta instancia de Selector; el segundo tipo es las colecciones SelectionKey devueltas por el método selectedKeys (), que representan los canales que requieren procesamiento IO El tercer tipo es el canal que no ha sido registrado y generalmente no se usa.
public class NioServerSocketDemo {

    private Selector selector;
    public static final int port = 30000;
    private Charset charset = Charset.forName("UTF-8");

    public void init() throws Exception{
        selector = Selector.open();
        ServerSocketChannel server = ServerSocketChannel.open();
        InetSocketAddress address = new InetSocketAddress("127.0.0.1",port);
        server.bind(address,5);
        server.configureBlocking(false);
        //serverSocketChannel也要注册到selector上面
        server.register(selector, SelectionKey.OP_ACCEPT);
        //selector.select()会阻塞当前线程
        //selector.select(long timeout),设置超时时间
        //selector.selectNow()不会阻塞线程
        while (selector.select()>0){
            for(SelectionKey key : selector.selectedKeys()){
                //已经处理过了,将其删除
                selector.selectedKeys().remove(key);
                if(key.isConnectable()){
                    SocketChannel channel = (SocketChannel)key.channel();
                    System.out.println(channel+" has connected...");
                }
                if(key.isAcceptable()){
                    SocketChannel acceptChannel = server.accept();
                    acceptChannel.configureBlocking(false);
                    acceptChannel.register(selector,SelectionKey.OP_READ);
                    key.interestOps(SelectionKey.OP_ACCEPT);
                }
                if(key.isReadable()){
                    SocketChannel channel = (SocketChannel)key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    String content = "";
                    try{
                        while (channel.read(buffer)>0){
                            buffer.flip();
                            content+=charset.decode(buffer);
                        }
                        System.out.println("get content:"+content);
                        channel.write(buffer);
                        key.interestOps(SelectionKey.OP_READ);

                    }catch (IOException ex){
                        key.cancel();
                        if(key.channel()!=null){
                            key.channel().close();
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        new NioServerSocketDemo().init();
    }

}

Usando AIO para realizar comunicación de socket sin bloqueo

public class AIOServerSocket {

    private static Charset charset = Charset.forName("UTF-8");
    public static void main(String[] args) throws Exception {
        AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(30000),1000);
        while (true){
            Future<AsynchronousSocketChannel> future = serverSocketChannel.accept();
            AsynchronousSocketChannel socketChannel = future.get();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            socketChannel.read(buffer);
            System.out.println("get from client:"+charset.decode(buffer));
        }
    }
}

Supongo que te gusta

Origin www.cnblogs.com/54chensongxia/p/12678143.html
Recomendado
Clasificación