当前位置:网站首页>NiO User Guide

NiO User Guide

2022-06-12 21:34:00 Besieged city_ city with high walls

preface

It's mainly about java.nio The relevant development tools under the package make a simple learning note , Not much in-depth discussion .

One 、 brief introduction

NIO namely New IO, This library is in JDK1.4 It was introduced in China .NIO and IO Have the same function and purpose , But the implementation is different ,NIO The main use is block , therefore NIO Is more efficient than IO Much higher . stay Java API Two sets of NIO, One is for standard input and output NIO, The other is network programming NIO. There is no better or worse ,NIO yes java io Development of , Depending on the scene , Both are useful .

1、NIO and IO The main difference

IONIO
Facing the flow Facing buffer
Blocking IO Non blocking IO
nothing Selectors

1.1、 Flow oriented and buffer oriented

Java IO and NIO The first big difference between them is ,IO yes Facing the flow Of ,NIO It's for buffer Of . Java IO Stream oriented means reading one or more bytes from the stream at a time , Until all bytes are read , They are not cached anywhere . Besides , It can't move the data in the stream back and forth . If you need to move the data read from the stream back and forth , You need to cache it to a buffer first . Java NIO The buffer oriented method is slightly different . The data is read to a buffer that it processes later , Move back and forth in the buffer if needed . This increases the flexibility of the process . however , You also need to check if the buffer contains all the data you need to process . and , Make sure that when more data is read into the buffer , Don't overwrite unprocessed data in the buffer .

1.2、 Blocking and non blocking IO

Java IO The various streams of are blocked . It means , When a thread calls read() or write() when , The thread is blocked , Until some data is read , Or write data completely . The thread can't do anything else during this period .Java NIO Non blocking mode of , Make a thread send a request to read data from a channel , But it can only get data that is currently available , If there is no data available , You will get nothing , Instead of keeping threads blocked , So until the data becomes readable , The thread can continue to do other things . So is nonblocking writing . A thread requests to write some data to a channel , But you don't have to wait for it to write completely , This thread can do other things at the same time . Threads will usually be non blocking IO Free time for execution on other channels IO operation , So a single thread can now manage multiple input and output channels (channel).

io The various streams of are blocked , When a thread calls a read-write method , The thread will be blocked , Until you finish reading and writing , During this time, the thread cannot do anything else ,CPU Turn to other threads , Suppose a thread listens to a port , There are only a few requests to come in a day , however CPU But I have to do context switching for the thread , And most of the switches end up blocking .

NIO Communication is to switch the whole task into many small tasks , One thread is responsible for handling all io event , And distribute . It is used. Event driven mechanism , Not a listening mechanism , Trigger again when the event arrives .NIO Between threads through wait,notify And so on . It ensures that every context switch is meaningful , Reduce unnecessary process switching .

1.3、 Selectors (Selectors)

Java NIO The selector allows a single thread to monitor multiple input channels , You can register multiple channels using a selector , Then use a separate thread to “ choice ” passageway : These channels already have inputs that can be processed , Or choose a channel that is ready to write to . This selection mechanism , Make it easy for a single thread to manage multiple channels .

Two 、 Buffers and pipes

Java NIO The core of the system is : passageway (Channel) And buffer (Buffer). The channel means open to IO equipment ( for example : file 、Socket) The connection of . If needed NIO System , Need to get used to connect IO The channel of the device and the buffer used to hold the data , Then operate on the buffer , Process the data .

  • In short ,Channel Responsible for transmission ,Buffer Responsible for the storage .

1、 buffer (Buffer)

  • buffer (Buffer): A container for a specific basic data type . from java.nio By definition , All buffers are Buffer A subclass of an abstract class .
  • Java NIO Medium Buffer Mainly used for and NIO Channels interact , Data is read into the buffer from the channel , Then write from the buffer to the... In the channel .
  • Buffer It's like an array ( In fact, it just encapsulates the array ), You can save multiple data of the same type . Depending on the type of data (boolean) With the exception of , There are the following Buffer Common subclasses :ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer. Above Buffer They all manage data in the same way as ah Yong , They just manage different data types .

1.1、 Basic properties of buffer

  • Capacity (capacity): Express Buffer Maximum data capacity , Buffer capacity cannot be negative , And once created it can't be changed .
  • Limit (limit): The first index of data that should not be read or written , It is located in limit The data after is not readable or writable . The buffer limit cannot be negative , And not more than the capacity .
  • Location (position): The index of the next data to read or write . Buffer position cannot be negative , And it can't be greater than its limit .
  • Mark (mark) And reset (reset): A tag is an index , adopt Buffer Medium mark() Method specification Buffer One of the specific position, After that, you can call reset() Method to recover to this position.

The size relationship of several basic attributes :0 <= mark <= position <= limit <= capacity.

1.2、Buffer The common method of

Method explain
Buffer clear() Clear the buffer and return a reference to the buffer
Buffer flip() Set the limit of the buffer to the current position , And set the current position to 0. Switch to read data mode .
int capacity() return Buffer Of capacity size
boolean hasRemaining() Determine whether there are still elements in the buffer
int limit() return Buffer The boundaries of (limit) The location of
Buffer limit(int n) Set the buffer limit to n, And returns a new limit Buffer object for
Buffer mark() Mark the buffer
int position() Returns the current location of the buffer position
Buffer position(int n) The current location of the buffer will be set to n, And return the modified Buffer object
int remaining() return position and limit The number of elements between
Buffer reset() Place position For previously set mark Where it is
Buffer rewind() Place position Set to 0, Unset mark

Manipulation of data :Buffer All subclasses provide two methods for data manipulation :get() and put() Method .

1.3、buffer Example use

public class BufferTest {
    

    @Test
    public void test1() {
    
        // Allocate a buffer of a specified size 
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        System.out.println("----------------allocate--------------");
        System.out.println("position:" + buffer.position());//0
        System.out.println("limit:" + buffer.limit());//1024
        System.out.println("capacity:" + buffer.capacity());//1024

        // utilize put() Method to store data in a buffer 
        String str = "abcde";
        buffer.put(str.getBytes());

        System.out.println("----------------put--------------");
        System.out.println("position:" + buffer.position());//5
        System.out.println("limit:" + buffer.limit());//1024
        System.out.println("capacity:" + buffer.capacity());//1024

        // Switch to read data mode 
        buffer.flip();
        System.out.println("----------------flip--------------");
        System.out.println("position:" + buffer.position());//0
        System.out.println("limit:" + buffer.limit());//5
        System.out.println("capacity:" + buffer.capacity());//1024

        // utilize get() Method to read data 
        byte[] dst = new byte[buffer.limit()];
        buffer.get(dst);

        System.out.println(" Get the data in the buffer :" + new String(dst, 0, dst.length));
        System.out.println("----------------get--------------");
        System.out.println("position:" + buffer.position());//5
        System.out.println("limit:" + buffer.limit());//5
        System.out.println("capacity:" + buffer.capacity());//1024

        // Read data repeatedly , Place position Set to 0
        buffer.rewind();
        System.out.println("----------------rewind--------------");
        System.out.println("position:" + buffer.position());//0
        System.out.println("limit:" + buffer.limit());//5
        System.out.println("capacity:" + buffer.capacity());//1024

        // Empty buffer , But the data in the buffer still exists , The data is in “ Forgotten state ”.
        buffer.clear();
        System.out.println("----------------clear--------------");
        System.out.println("position:" + buffer.position());//0
        System.out.println("limit:" + buffer.limit());//1024
        System.out.println("capacity:" + buffer.capacity());//1024
    }

    @Test
    /** * mark() And reset Example  * */
    public void test2() {
    
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        String str = "abcde";
        buffer.put(str.getBytes());

        buffer.flip();

        byte[] dst = new byte[buffer.limit()];
        buffer.get(dst,0,2);
        System.out.println(new String(dst,0,2));

        System.out.println("position:"+buffer.position());//2

        buffer.mark();

        buffer.get(dst,2,2);

        System.out.println(new String(dst,2,2));

        System.out.println("position:"+buffer.position());//4

        buffer.reset();

        System.out.println("position:"+buffer.position());//2

        // Determine whether the buffer contains remaining data 
        if(buffer.hasRemaining()){
    
            System.out.println(" Get the number of operations in the buffer "+buffer.remaining());
        }

    }
}

 Insert picture description here

1.4、 Direct buffer and indirect buffer

  • The byte buffer is either direct , It's either indirect . If it's a direct byte buffer , be Java The virtual machine does its best to execute the native directly on this buffer IO operation . in other words , In every call to the underlying operating system of a native I/O Before the operation ( Or after ), Virtual machines try to avoid copying the contents of the buffer to the middle buffer ( Or copy content from the middle buffer ).

  • The direct byte buffer can be used by calling allocateDirect() Factory method to create . The cost of allocating and deallocating the buffer returned by this method is usually higher than that of indirect buffer . The contents of the direct buffer can reside outside the regular garbage collection heap , therefore , Their impact on the memory requirements of the application may not be obvious . therefore , It is recommended to allocate the direct buffer mainly to the local areas that are vulnerable to the underlying system IO Operate the corresponding large 、 Persistent buffer . In general , It's best to allocate direct buffers only when they provide significant benefits in terms of program performance .

  • The direct byte buffer can also be passed through FileChannel Of map() Method maps the file area directly into memory to create . This method returns MappedByteBuffer.Java The implementation of the platform helps through JNI Create a direct byte buffer from native code . If one of the above buffer instances refers to an inaccessible memory area , Then trying to access the area will not change the contents of the buffer , And it will cause an indefinite exception to be thrown during the visit or at a later time .
    Whether the byte buffer is a direct buffer or an indirect buffer can be passed through isDirect() Method to determine . This method is provided to enable display buffer management in performance critical code .
     Insert picture description here
     Insert picture description here
    About kernel address space and user address space ,《Linux Kernel space versus user space 》 The blog gives a detailed explanation , You can go and have a look if you are interested .

2、 passageway

passageway (Channel): from java.nio.channels By definition .Channel Express IO Open links between source and target .Channel Similar to the traditional “ flow ”. It's just CHannel You can't access data directly by yourself ,Channel And the only Buffer Interact .
 Insert picture description here

2.1、 The main entity class of the channel

Java by Channel(java.nio.channels.Channel) The main implementation classes provided by the interface are as follows :

  • FileChannel: For reading 、 write in 、 Channels for mapping and manipulating files .
  • DatagramChannel: adopt UDP Read and write data channels in the network .
  • SocketChannel: adopt TCP Read and write data in the network .
  • ServerSocketChannel: You can monitor new arrivals TCP Connect , A new connection will be created for each new connection SocketChannel.

2.2、 Get channel mode

  • ①Java Provided for classes that support channels getChannel() Method

      -  FileInputStream
      -  FileOutputStream
      -  RandomAccessFile
      -  Socket
      -  ServerSocket
      -  DatagramSocket
    
  • ②JDK1.7 Medium NIO2 Provides static methods for each channel open() Method .

  • ③JDK1.7 Medium NIO2 Of Files The utility class newByteChannel() Method .

2.3、 file channel (FileChannel)

FileChannel Objects cannot be created directly . One FileChannel Instances can only be accessed through an open file object (RandomAccessFile、FileInputStreamFileOutputStream or FileChannel Of open Static method acquisition ) On the call getChannel( ) Method to get . call getChannel( ) Method returns a connection to the same file FileChannel Object and the FileChannel Object has the same meaning as file Object with the same access rights , You can then use this channel object to take advantage of the powerful FileChannel API 了 . Also note that , File channels are blocked , Only network channels can be non blocking .

(1) Common methods of file channel

Method describe
int read(ByteBuffer dst) from Channel Read data to ByteBuffer
long read(ByteBuffer[] dsts) take Channel Data in “ Dispersed ” To ByteBuffer[]
int write(ByteBuffer src) take ByteBuffer The data in is written to Channel
long write(ByteBuffer[] srcs) take ByteBuffer[] Data in “ Gather ” To Channel
long position() Returns the file location of this channel
FileChannel position(long p) Set the file location for this channel
long size() Returns the current size of the file for this channel
FileChannel truncate(long s) Intercept the file of this channel to the given size
void force(boolean metaData) Force all file updates for this channel to be written to the storage device

(2) File channel copy file application example :

package com.xsl.nio;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/** *  One 、 passageway (Channel): Used for connection between source node and target node . stay Java NIO Is responsible for the transmission of data in the buffer .Channel It does not store data , Therefore, you need to cooperate with the buffer to operate . *  Two 、 The main implementation class of the channel  * java.nio.channels.Channel Interface  * |--FileChannel * |--SocketChannel * |--ServerSocketChannel * |--DatagramChannel *  3、 ... and 、 Get access to  * ①Java Classes that support channels provide getChannel() Method . *  Local IO:FileInputStream、FileOutputStream、RandomAccessFile *  The Internet IO:Socket、ServerSocket、DatagramSocket * ② stay JDK1.7 Medium NIO2 Static methods are provided for each channel open(). * ③ stay JDK1.7 Medium NIO2 Of Files The utility class newByteChannel(). *  Four 、 Data transmission between channels  * transferFrom() * transferTo() */
public class ChannelTest {
    

    /** *  Use the direct buffer to copy the file  * @throws IOException */
    @Test
    public void test3() throws IOException {
    
        FileChannel inFileChannel = FileChannel.open(Paths.get("D:\\project\\nio\\1.jpg"), StandardOpenOption.READ);
        FileChannel outFileChannel = FileChannel.open(Paths.get("D:\\project\\nio\\2.jpg"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);

        inFileChannel.transferTo(0, inFileChannel.size(), outFileChannel);
// outChannel.transferFrom(inChannel,0,inChannel.size());

        outFileChannel.close();
        inFileChannel.close();
    }


    /** *  Use the direct buffer to copy the file ( Memory mapped files ) */
    @Test
    public void test2() throws IOException {
    
        FileChannel inFileChannel = FileChannel.open(Paths.get("D:\\project\\nio\\1.jpg"), StandardOpenOption.READ);
        FileChannel outFileChannel = FileChannel.open(Paths.get("D:\\project\\nio\\2.jpg"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);

        // Memory mapped files 
        MappedByteBuffer inMappedByteBuffer = inFileChannel.map(FileChannel.MapMode.READ_ONLY, 0, inFileChannel.size());
        MappedByteBuffer outMappedByteBuffer = outFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, inFileChannel.size());

        // Read and write data directly to the buffer 
        byte[] dst = new byte[inMappedByteBuffer.limit()];
        inMappedByteBuffer.get(dst);

        outMappedByteBuffer.put(dst);

        inFileChannel.close();
        outFileChannel.close();
    }


    /** *  Use the channel to copy the file ( Indirect buffer ) * * @throws IOException */
    @Test
    public void test() throws IOException {
    
        FileInputStream fileInputStream = new FileInputStream("D:\\project\\nio\\1.jpg");
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\project\\nio\\2.jpg");

        //① Get access to 
        FileChannel fileInputStreamChannel = fileInputStream.getChannel();
        FileChannel fileOutputStreamChannel = fileOutputStream.getChannel();

        //② Allocate buffer of specified size 
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        //③ Store the data in the channel into the buffer 
        while (-1 != fileInputStreamChannel.read(buffer)) {
    
            buffer.flip();
            //④ Write the data of the buffer to the channel 
            fileOutputStreamChannel.write(buffer);
            // Empty buffer 
            buffer.clear();
        }

        fileOutputStreamChannel.close();
        fileInputStreamChannel.close();
        fileOutputStream.close();
        fileInputStream.close();


    }
}

3、 The channels are scattered over the aggregates

Distributed read (Scattering Reads) From Channel Data read in “ Dispersed ” To more than one Buffer in . That is, in the order of buffers , from Channel The data read in will be Buffer fill .
 Insert picture description here
Aggregate write (Gathering Writes) It means that multiple Buffer Data in “ Gather ” To Channel. In the order of buffers , write in position and limit Data to Channel.
 Insert picture description here
Application example

package com.xsl.nio;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ChannelTest {
    

    @Test
    public void test() throws IOException {
    
		// Create file stream 
        FileInputStream fileInputStream = new FileInputStream("D:\\project\\nio\\1.jpg");
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\project\\nio\\2.jpg");
		// Get access to 
        FileChannel fileInputStreamChannel = fileInputStream.getChannel();
        FileChannel fileOutputStreamChannel = fileOutputStream.getChannel();
		// Create buffer 
        ByteBuffer buffer1 = ByteBuffer.allocate(512);
        ByteBuffer buffer2 = ByteBuffer.allocate(512);
		// Scattered read buffer array 
        ByteBuffer[] buffers = new ByteBuffer[]{
    buffer1, buffer2};
        // Read 
        while (-1 != fileInputStreamChannel.read(buffers)) {
    
            for (ByteBuffer buffer : buffers) {
    
                buffer.flip();
            }
            fileOutputStreamChannel.write(buffers);
            for (ByteBuffer buffer : buffers) {
    
                buffer.clear();
            }
        }
        fileInputStreamChannel.close();
        fileOutputStreamChannel.close();
        fileInputStream.close();
        fileOutputStream.close();

    }
}

3、 ... and 、NIO Non blocking network communication

1、 Blocking and non blocking

  • Conventional IO The flow is blocked . in other words , When a thread calls read() after write() Method time , The thread will be blocked , Until some data is read or written , This thread cannot perform other tasks during this time . therefore , At the completion of network communication IO In operation , Because threads will block , So the server must provide a separate thread for each client to process , When the server needs to process a large number of client requests , Sharp performance degradation .
  • Java NIO It's non blocking . When a thread reads or writes data from a channel , If no data is available , This thread can perform other tasks . Threads will usually be non blocking IO Space time of is used to execute on other channels IO operation , So a single thread can manage multiple input and output channels . therefore ,NIO The server side can use one or a limited number of threads to handle all clients connected to the server side at the same time .

2、 Network channel

2.1、SocketChannel

Java NIO Medium SocketChannel Is a connection to TCP The channel of the network socket .

Operation steps :

  1. open SocketChannel passageway
  2. Reading data
  3. close SocketChannel passageway

2.2、ServerSocketChannel

Java NIO Medium ServerSOcketChannel It's a new one that can monitor TCP Connecting channels , Like the standard IO Medium ServerSocket equally .

2.3、DatagramChannel

DatagramChannel It's a support UDP Protocol transceiver network channel

Operation steps :

  1. open DatagramChannel passageway
  2. Sending and receiving data

3、 Selectors (Selecter)

Selectors (Selector) yes SelectableChannel Object multiplexer ,Selector You can monitor multiple SelectableChannel Of IO condition , in other words , utilize Selector This allows a single thread to manage multiple threads Channel.Selector Yes no blocking IO At the heart of .

SelectableChannel The structure of is shown in the figure below :
 Insert picture description here

3.1、 Common methods of selectors

Method describe
Set keys() Return all SelectionKey aggregate . The representative is registered in the Selector Upper Channel
Set selectedKeys() Back here Selector Selected key for
int select() Monitor all registered Channel, If there is something to deal with IO During operation , The corresponding SelectionKey Join the selected SelectionKey Set set , And return these Channel The number of .
int select(long timeout) You can set the timeout length select() operation
int selectNow() Execute an immediate return select() operation , This method does not block threads
Selector wakeup() Make an unreturned select() Method returns immediately
void close() Close the selector

3.2、 Selector listens for events

When calling register(Selector sel,int ops) When registering a channel with a selector , The selector listens to the channel events , You need to pass the second parameter ops To specify the .

Types of events that can be monitored ( have access to SelectionKey Four constants of ):

  • read :SelectionKey.OP_READ.
  • Write :SelectionKey.OP_WRITE.
  • Connect :SelectionKey.OP_CONNECT.
  • receive :SelectionKey.OP_ACCEPT.

If you listen to more than one event during registration , have access to "|" Operator join .

int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;

3.3、SelectionKey

SelectionKey Express SelectableChannel and Selector The registration relationship between . Each time a channel is registered with the selector, an event is selected ( Selection key ).

Method describe
int interestOps() Get the collection of events of interest
int readyOps() Gets the collection of operations for which the channel is ready
SelectableChannel channel() Get the registration channel
Selector selector() Return selector
boolean isReadable() testing Channel Whether the medium reading event is ready
boolean isWriteable() testing Channel Whether the write event is ready
boolean isConnectable() testing Channel Ready... Connecting
boolean isAcceptable() testing Channel Whether the acceptance is ready

3.4、 Application example

NIO Blocking type

package com.xsl.nio;



import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/** *  One 、 Use NIO Three cores of network communication : * ① passageway (Channel): Responsible for the connection . * java.nio.channels.Channel Interface : * |--SelectableChannel * |--SocketChannel * |--ServerSocketChannel * |--DatagramChannel * * |--Pipe.SinkChannel * |--Pipe.SourceChannel * ② buffer (Buffer): Responsible for data access . * ③ Selectors (Selector): yes SelectableChannel Multiplexer of . Used to monitor SelectableChannel Some of IO condition . */
public class BlockingNIOTest {
    

    @Test
    public void client() throws IOException {
    
        // Get access to 
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(9898));

        FileChannel fileChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);

        // Allocate buffer of specified size 
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // Read local file , And send it to the server 
        while (-1 != fileChannel.read(buffer)) {
    
            buffer.flip();
            socketChannel.write(buffer);
            buffer.clear();
        }

        // Notify the server that the transfer is complete 
        socketChannel.shutdownOutput();

        int len = 0;

        while ((len = socketChannel.read(buffer)) != -1) {
    
            buffer.flip();
            System.out.println(new String(buffer.array(),0,len));
            buffer.clear();
        }


        fileChannel.close();
        socketChannel.close();
    }

    @Test
    public void server() throws IOException {
    
        // Get access to 
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // Binding port number 
        serverSocketChannel.bind(new InetSocketAddress(9898));

        SocketChannel socketChannel = serverSocketChannel.accept();

        FileChannel fileChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);

        // Allocate buffer of specified size 
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        while (-1 != socketChannel.read(buffer)) {
    
            buffer.flip();
            fileChannel.write(buffer);
            buffer.clear();
        }

        buffer.put(" Server side acceptance succeeded ".getBytes());
        buffer.flip();

        socketChannel.write(buffer);


        fileChannel.close();
        socketChannel.close();
    }


}

NIO Non-blocking type

package com.xsl.nio;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;

public class NOBlockingNIOTest {
    
    @Test
    public void client() throws IOException {
    
        // Get access to 
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(9897));
        // Switch to non blocking mode 
        socketChannel.configureBlocking(false);
        // Allocate buffer of specified size 
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        // Send data to the server 
        buffer.put(new Date().toString().getBytes());
        buffer.flip();
        socketChannel.write(buffer);
        // Close channel 
        socketChannel.close();
    }

    @Test
    public void server() throws IOException {
    
        // Get access to 
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // Switch to non blocking mode 
        serverSocketChannel.configureBlocking(false);
        // Binding port 
        serverSocketChannel.bind(new InetSocketAddress(9897));
        // Get selector 
        Selector selector = Selector.open();
        // Register the channel to the selector , And specify listening events 
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        // The polling get selector already “ Be ready ” Events 
        while (selector.select() > 0) {
    
            // Get all registered... In the current selector “ Selection key ( Registered listening Events )”
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            // Traverse 
            while (iterator.hasNext()) {
    
                SelectionKey selectionKey = iterator.next();
                // Determine exactly what event is ready 
                if (selectionKey.isAcceptable()) {
    
                    // If it is “ Ready to accept ”, Get client connection 
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    // Switch to non blocking mode 
                    socketChannel.configureBlocking(false);
                    // Register the channel to the selector 
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (selectionKey.isReadable()) {
    
                    // Get the current selector on “ Read ready ” The channel of state 
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    // Reading data 
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int len = 0;
                    while ((len = socketChannel.read(buffer)) != -1) {
    
                        buffer.flip();
                        System.out.println(new String(buffer.array(), 0, len));
                        buffer.clear();
                    }
                }
                // Deselect key 
                iterator.remove();
            }
        }
    }
}

原网站

版权声明
本文为[Besieged city_ city with high walls]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/163/202206122125175526.html