1. Introduction
1. NIO's full name is non blocking IO, which refers to the new API provided by JDK. From jdk1 Since the beginning of 4, Java has provided a series of improved input / output new features, called NIO(new IO), which are synchronous and non blocking.
2. NIO classes are placed in Java NiO and its sub packages, and Java Many classes of IO package are transformed.
3. NIO has three core parts: Channel, Buffer and Selector. The Selector can select a Channel, which interacts with the Buffer buffer, and the client interacts with the Buffer buffer.
4. NIO is buffer oriented or block oriented. The data is read to a buffer that it will process later, and can move back and forth in the buffer when needed, which increases the flexibility of the processing process. It can provide a non blocking and highly scalable network.
5. The non blocking mode of javanio enables a thread to send or request data from a channel, but it can only get the currently available data. If there is no currently available data, nothing will be read instead of keeping the thread blocked. So when the data is readable, the thread can do other things. The same is true for non blocking write. A thread requests to write some data to a channel, but it can do other things without waiting for it to write completely.
6. Generally speaking, NIO can handle multiple operations with one thread.
7. HTTP2.0 uses multiplexing technology to process multiple requests simultaneously in the same connection, and the number of concurrent requests is higher than that of http1 1 is several orders of magnitude larger.
2. Relationship between bio and NIO
1. BIO processes data in stream mode, while NIO processes data in block mode. The efficiency of block I/O is much higher than that of stream I/O
2. BIO is blocking, while NIO is non blocking
3. BIO operates based on byte stream and character stream, while NIO operates based on channel and buffer. Data is always read from the channel to the buffer or written from the buffer to the channel. The selector is used to listen for events of multiple channels (such as connection request, data arrival, etc.), so a single thread can listen to multiple client channels.
3. Relationship between the three components
1> One thread corresponds to one Selector, and one Selector corresponds to multiple channel s
2> Each channel corresponds to a buffer
3> Which channel the program switches to is determined by the event. Event is an important concept; The Selector will switch in different channels according to different events
4> Buffer is a memory block, and there is an array at the bottom
5> Data is read and written through buffer, which is different from BIO. BIO stream is either input stream or output stream, and cannot be bidirectional. NIO buffer is bidirectional, readable and writable, and needs to be switched by flip() method.
6> The channel is also bidirectional and can return the operation of the underlying operating system. For example, the operating system channel at the bottom of Linux is bidirectional.
4. Buffer mechanism and its subclasses
Buffer has four important attributes:
// Invariants: mark <= position <= limit <= capacity private int mark = -1; private int position = 0; private int limit; private int capacity;
Capacity refers to the capacity, that is, the maximum storage quantity
Limit indicates the current end point of the buffer. Read and write operations cannot be performed at the position where the buffer exceeds the limit. And the limit can be modified.
position the index of the next element to be read or written
Mark mark
Class inheritance relationship is as follows:
The eight basic data types, except bool, all have corresponding buffers. The most commonly used is ByteBuffer. When reading data, it is put into the corresponding buffer according to the data type. And each sub buffer has its subclasses, and each buffer has an array for storing data. For example, IntBuffer is as follows:
final int[] hb; // Non-null only for heap buffers final int offset; boolean isReadOnly; // Valid only for heap buffers
The tests are as follows:
(1) Testing is simple to use
package cn.qlq; import java.nio.IntBuffer; public class BufferTestCase { public static void main(String[] args) { IntBuffer buffer = IntBuffer.allocate(5); // Store data for (int i = 0; i < buffer.capacity(); i++) { buffer.put(i * 2); } // buffer Read write switching buffer.flip(); // Read data while (buffer.hasRemaining()) { System.out.println(buffer.get()); } } }
result:
0
2
4
6
8
Viewing the source code of flip is actually changing the position where the limit is position and setting the position to 0.
public final Buffer flip() { limit = position; position = 0; mark = -1; return this; }
(2) Test and modify limit and position
public static void main(String[] args) { IntBuffer buffer = IntBuffer.allocate(5); // Store data for (int i = 0; i < buffer.capacity(); i++) { buffer.put(i * 2); } // buffer Read write switching buffer.flip(); // modify limit and position buffer.limit(3); buffer.position(1); // Read data while (buffer.hasRemaining()) { System.out.println(buffer.get()); } }
result:
2
4
(3) Introduction to other methods
buffer.clear(); // Clear the buffer and restore each tag to the original tag, but the data is unclear
put(int index, byte b) inserts data into the specified location
get(int index) reads the data at the specified location
Test:
public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(5); // Store data buffer.put(2, (byte) 2); // buffer Read write switching buffer.flip(); // Reverse buffer // modify limit and position buffer.clear(); // Clear the buffer and restore each tag to the original tag, but the data is unclear System.out.println(buffer.get(2)); }
result:
2
(4) buffer supports typed put and get. For the type of data put in, the corresponding data type should be used to get out, otherwise an error will be reported: BufferUnderflowException. Of course, if automatic type conversion is possible, no error will be reported
ByteBuffer buffer = ByteBuffer.allocate(512); buffer.putInt(1); buffer.putLong(2L); buffer.putShort((short)2); buffer.putChar('2'); // Switch between read and write buffer.flip(); System.out.println(buffer.getInt()); System.out.println(buffer.getLong()); System.out.println(buffer.getShort()); System.out.println(buffer.getLong());
result:
1 2 2 Exception in thread "main" java.nio.BufferUnderflowException at java.nio.Buffer.nextGetIndex(Buffer.java:506) at java.nio.HeapByteBuffer.getLong(HeapByteBuffer.java:412) at nio.ChannelTest.bufferTest(ChannelTest.java:29) at nio.ChannelTest.main(ChannelTest.java:13)
(5) buffer can be set to read-only, and an error will be reported when writing
ByteBuffer buffer = ByteBuffer.allocate(512); System.out.println(buffer.getClass()); System.out.println(buffer.isReadOnly()); ByteBuffer byteBuffer = buffer.asReadOnlyBuffer(); System.out.println(buffer.getClass()); System.out.println(byteBuffer.isReadOnly()); byteBuffer.putLong(2L);
result:
class java.nio.HeapByteBuffer false class java.nio.HeapByteBuffer true Exception in thread "main" java.nio.ReadOnlyBufferException at java.nio.HeapByteBufferR.putLong(HeapByteBufferR.java:426) at nio.ChannelTest.bufferTest(ChannelTest.java:25) at nio.ChannelTest.main(ChannelTest.java:13)
(6) NIO also provides MappedByteBuffer, which allows files to be modified directly in memory (off heap memory), and NIO completes how to synchronize to files
The class diagram is as follows:
You can see that the bottom layer is a read-only Buffer
1> The tests are as follows:
// Open file 1 in read-write mode.txt RandomAccessFile file = new RandomAccessFile("1.txt", "rw"); FileChannel channel = file.getChannel(); /** * Map to mappedbytebuffer (read / write mode, starting from 0, mapping up to five, that is, up to five can be modified in memory) * */ MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5); mappedByteBuffer.putChar(3, '3'); file.close(); System.out.println("Modified successfully" + mappedByteBuffer.getClass());
Result: the file will be updated successfully. Finally, the console will print as follows:
Modified successfully class java.nio.DirectByteBuffer
2> Test 2: an exception is reported when the index is modified to 5
// Open file 1 in read-write mode.txt RandomAccessFile file = new RandomAccessFile("1.txt", "rw"); FileChannel channel = file.getChannel(); /** * Mapped to mappedbytebuffer (read / write mode, starting from 0, mapping up to five, that is, up to five can be modified in memory = 0-4) * */ MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5); mappedByteBuffer.putChar(3, '3'); mappedByteBuffer.putChar(5, '3'); file.close(); System.out.println("Modified successfully" + mappedByteBuffer.getClass());
result:
Exception in thread "main" java.lang.IndexOutOfBoundsException at java.nio.Buffer.checkIndex(Buffer.java:546) at java.nio.DirectByteBuffer.putChar(DirectByteBuffer.java:533) at nio.ChannelTest.bufferTest(ChannelTest.java:30) at nio.ChannelTest.main(ChannelTest.java:14)
(7) buffer can also be used as an array to complete read and write operations, namely scattering and gathering
// use ServerSocketChannel and SocketChannel ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // Binding port InetSocketAddress inetSocketAddress = new InetSocketAddress(7000); serverSocketChannel.socket().bind(inetSocketAddress); ByteBuffer[] byteBuffers = new ByteBuffer[2]; byteBuffers[0] = ByteBuffer.allocate(5); byteBuffers[1] = ByteBuffer.allocate(3); SocketChannel socketChannel = serverSocketChannel.accept(); int msgLength = 8; while (true) { int readed = 0; while (readed < msgLength) { long l = socketChannel.read(byteBuffers); readed += l; System.out.println("readed: " + readed); Arrays.asList(byteBuffers).stream() .map(buffer -> "position = " + buffer.position() + ", limit = " + buffer.limit()) .forEach(System.out::println); Arrays.asList(byteBuffers).stream() .forEach(buffer -> System.out.println("data: " + new String(buffer.array()))); } // Data display to client Arrays.asList(byteBuffers).stream().forEach(buffer -> buffer.flip()); long byteWrite = 0; while (byteWrite < msgLength) { long l = socketChannel.write(byteBuffers); byteWrite += l; } Arrays.asList(byteBuffers).stream().forEach(buffer -> buffer.clear()); System.out.println("byteWrite = " + byteWrite + ", readed = " + readed + " , msgLength = " + msgLength); }
Test:
1> telnet connection
telnet 127.0.0.1 7000
2>Ctrl +]
3> Send command
Microsoft Telnet> send hello123
Send string hello123
4> The console log is as follows
readed: 8
position = 5, limit = 5
position = 3, limit = 3
data: hello
data: 123
byteWrite = 8, readed = 8 , msgLength = 8
5. Channel
1. Introduction
1. NIO channel is similar to stream, but there are differences:
(1) Channels can read or write at the same time, while streams can only read or write
(2) The channel can read and write data asynchronously
(3) The channel can read data from the buffer or write data to the buffer
2. Channel is an interface in NIO. There are many sub interfaces and main implementations below. The main achievements are:
FileChannel is used to read and write data of files, datagram channel is used to read and write data of UDP, and ServerSocketChannel and SocketChannel are used to read and write data of TCP.
2. FileChannel is easy to use
1. Simply use FileChannel to write string to file:
private static void fileChannelTest() throws Exception { String string = "hello,China!"; FileOutputStream fileOutputStream = new FileOutputStream("F:/test.txt"); // adopt FileOutputStream obtain FileChannelImpl FileChannel channel = fileOutputStream.getChannel(); // Create a buffer ByteBuffer byteBuffer = ByteBuffer.allocate(1024); // Data put buffer byteBuffer.put(string.getBytes()); // yes buffer conduct flip Switch between read and write byteBuffer.flip(); channel.write(byteBuffer); fileOutputStream.close(); }
After put ting, debug to check the buffer information: (one Chinese character takes up three bytes, seven English letters plus two Chinese characters, so it is 13 bytes)
2. Use FileChannel to read files:
package cn.qlq; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class ChannelTest { public static void main(String[] args) throws Exception { fileChannelTest(); } private static void fileChannelTest() throws Exception { File file = new File("F:/test.txt"); FileInputStream inputStream = new FileInputStream(file); // adopt FileInputStream obtain FileChannelImpl FileChannel channel = inputStream.getChannel(); // Create a buffer ByteBuffer byteBuffer = ByteBuffer.allocate((int)file.length()); // Data read into buffer channel.read(byteBuffer); System.out.println(new String(byteBuffer.array())); inputStream.close(); } }
result:
hello, China!
3. Use FileChannel to read one file and write to another:
@SneakyThrows private static void fileChannelTest() { FileInputStream inputStream = new FileInputStream("1.txt"); FileChannel channel1 = inputStream.getChannel(); FileOutputStream outputStream = new FileOutputStream("2.txt"); FileChannel channel2 = outputStream.getChannel(); // Create a buffer ByteBuffer byteBuffer = ByteBuffer.allocate(512); while (true) { int read = channel1.read(byteBuffer); if (read == -1) { break; } byteBuffer.flip(); channel2.write(byteBuffer); //Key operations. empty Buffer, Reset key attributes. Without this step, it will always be read To 0 byteBuffer.clear(); System.out.println(read); } inputStream.close(); outputStream.close(); }
4 . FileChannel enables file copying
@SneakyThrows private static void fileChannelTest() { FileInputStream inputStream = new FileInputStream("1.txt"); FileChannel channel1 = inputStream.getChannel(); FileOutputStream outputStream = new FileOutputStream("3.txt"); FileChannel channel2 = outputStream.getChannel(); // channel Copy, from input stream channel Copy to output stream channel channel2.transferFrom(channel1, 0, channel1.size()); inputStream.close(); outputStream.close(); }
After the above four examples, I understand. Each Stream contains a Channel. Writing or reading to the Channel will be operated on the corresponding Stream.
6. Selector
1. NIO of Java uses non blocking IO mode. One thread can be used to process multiple client connections, and the selector will be used
2. The selector can detect whether events occur on multiple registered channels (multiple channels can be registered to the selector in the form of events). If an event occurs, it will obtain the event and then process each event accordingly. In this way, it can manage multiple channels with only one single thread, that is, manage multiple connections and requests
3. Only when the connection has a real read-write event can it be read and written, which greatly reduces the system overhead, and there is no need to create a thread for each connection and maintain multiple threads
4. Avoid the context between multiple threads and the overhead caused by eye protection
characteristic:
(1) Netty's IO thread NioEventLoop aggregates selectors (selectors, also known as multiplexers), which can handle hundreds of client connections simultaneously
(2) When a thread reads and writes data from a client Socket channel, the thread can perform other tasks when no data is available
(3) Thread channels use the idle time of non blocking IO to perform IO operations on other channels, so a single thread can manage multiple input and output channels
(4) Since read and write operations are non blocking, this can fully improve the running efficiency of IO threads and avoid thread suspension caused by frequent IO blocking
(5) One IO thread can handle N client connections and read-write operations concurrently, which fundamentally solves the traditional synchronous blocking IO connection thread model, and greatly improves the performance, scalability and reliability of the architecture
The source code of Selector is as follows:
public abstract class Selector implements Closeable { protected Selector() { } public static Selector open() throws IOException { return SelectorProvider.provider().openSelector(); } public abstract boolean isOpen(); public abstract SelectorProvider provider(); public abstract Set<SelectionKey> keys(); public abstract Set<SelectionKey> selectedKeys(); public abstract int selectNow() throws IOException; public abstract int select(long var1) throws IOException; public abstract int select() throws IOException; public abstract Selector wakeup(); public abstract void close() throws IOException; }
Core method:
open gets a Selector object, that is, the method to get the Selector.
select() selects a prepared key set to prepare for IO operations. This is a blocking method, which will block the acquisition of data.
select(long var1) monitors all registered channels. When there are IO operations available, the corresponding SelectionKey is added to the internal collection and returned. The parameter is used to set the timeout, which is non blocking. SelectionKey is an element in the internal collection of existing objects. Through SelectionKey, you can obtain information such as Channel and registered events (read and write).
selectNow() is also non blocking. It just gets it. If there is a SelectionKey, it will be added to the internal collection, and if there is no SelectionKey, it will be discarded.
1. Relationships related to NIO non blocking network programming (Selector, SelectionKey, ServerScoketChannel and SocketChannel)
1. When the client connects, it will get the SocketChannel through ServerSocketChannel
2. The selector listens to the select method and returns the number of channels with events
3. Register socketchannels on the selector, register(Selector sel, int ops). Multiple socketchannels can be registered on a selector. ops represents registered events.
java.nio.channels.SelectionKey#OP_READ read event
java.nio.channels.SelectionKey#OP_WRITE write event
java.nio.channels.SelectionKey#OP_CONNECT connection establishment success event
java.nio.channels.SelectionKey#OP_ACCEPT has a new connection event
4. After registration, a SelectionKey will be returned, which will be associated with the Selector (set)
5. Further obtain each SelectionKey (event occurs)
6. After obtaining SocketChannel in reverse through SelectionKey, the method channel()
7. Business processing can be completed through the obtained channel
2. Test:
(1) Server source code
package nio; 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.Iterator; import java.util.Set; public class NIOServer { public static void main(String[] args) throws Exception { // establish ServerSocketChannel -> ServerSocket // Java NIO Medium ServerSocketChannel It's a new one who can monitor new arrivals TCP Connected channel, Like standard IO Medium ServerSocket Same. ServerSocketChannel Class in java.nio.channels In the package. // By calling ServerSocketChannel.open() Method to open ServerSocketChannel.For example: ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // Get one Selecor object (sun.nio.ch.WindowsSelectorImpl) Selector selector = Selector.open(); //Bind a port 6666, Listen on the server side serverSocketChannel.socket().bind(new InetSocketAddress(6666)); //Set to non blocking serverSocketChannel.configureBlocking(false); //hold serverSocketChannel Register to selector The concerned events are OP_ACCEPT //SelectionKey 4 events defined in //SelectionKey.OP_ACCEPT - The receive connection progress event indicates that the server has listened to the client connection, so the server can receive the connection // SelectionKey.OP_CONNECT - The connection ready event indicates that the connection between the client and the server has been established successfully //SelectionKey.OP_READ - The read ready event indicates that the channel has readable data and can be read (the channel currently has data and can be read) //SelectionKey.OP_WRITE - Write ready event, indicating that data can be written to the channel (the channel can be used for write operation at present) serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Registered selectionkey quantity=" + selector.keys().size()); // 1 //Cycle waiting for client connection while (true) { //Here we wait one second if no event happens, return if (selector.select(1000) == 0) { //No events occurred // System.out.println("The server waited for 1 second and there was no connection"); continue; } //If returned>0, Get the relevant information selectionKey aggregate //1.If returned>0, Indicates an event that has received attention //2. selector.selectedKeys() Returns a collection of events of interest // adopt selectionKeys Reverse acquisition channel Set<SelectionKey> selectionKeys = selector.selectedKeys(); System.out.println("selectionKeys quantity = " + selectionKeys.size()); //hasNext() : This method will judge whether the collection object has the next element. If it is already the last element, it will return false. //next(): Move the pointer of the iterator to the next position, and the method returns the reference of the next element. //remove() Removes the last element returned by the iterator from the collection pointed to by the iterator. //ergodic Set<SelectionKey>, Traversal using iterators Iterator<SelectionKey> keyIterator = selectionKeys.iterator(); while (keyIterator.hasNext()) { //Get SelectionKey SelectionKey key = keyIterator.next(); //according to key Handle the events of the corresponding channel accordingly if (key.isAcceptable()) { //If it is OP_ACCEPT, There is a new client connection //The client generates a SocketChannel SocketChannel socketChannel = serverSocketChannel.accept(); System.out.println("Client connection successfully generated a socketChannel " + socketChannel.hashCode()); //take SocketChannel Set to non blocking socketChannel.configureBlocking(false); //take socketChannel Register to selector, The event of concern is OP_READ, Give at the same time socketChannel Associate a Buffer socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024)); System.out.println("After the client connects, the registered selectionkey quantity=" + selector.keys().size()); //2,3,4.. } if (key.isReadable()) { //happen OP_READ //adopt key Reverse obtain the corresponding channel SocketChannel channel = (SocketChannel) key.channel(); //Get the channel Associated buffer ByteBuffer buffer = (ByteBuffer) key.attachment(); channel.read(buffer); System.out.println("from client: " + new String(buffer.array())); } //Move manually from the current collection selectionKey, Prevent repeated operations keyIterator.remove(); } } } }
(2) Client code
package nio; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class NIOClient { public static void main(String[] args) throws Exception { //Get a network channel SocketChannel socketChannel = SocketChannel.open(); //Set non blocking socketChannel.configureBlocking(false); //Provide server-side ip And port InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 6666); //Connect server if (!socketChannel.connect(inetSocketAddress)) { while (!socketChannel.finishConnect()) { System.out.println("Because the connection takes time, the client will not block and can do other work.."); } } //If the connection is successful, send the data String str = "hello, China ~ "; //Wraps a byte array into a buffer ByteBuffer buffer = ByteBuffer.wrap(str.getBytes()); //Send data to buffer Data writing channel socketChannel.write(buffer); System.in.read(); } }
Result: server side console
selectionKeys quantity = 1 Client connection successfully generated a socketChannel 1722023916 After the client connects, the registered selectionkey quantity=2 selectionKeys quantity = 1 from client hello, China~
3. Summary
1 SelectionKey: refers to the registration relationship between the Selector and the network channel. There are four types:
java.nio.channels.SelectionKey#OP_READ read event
java.nio.channels.SelectionKey#OP_WRITE write event
java.nio.channels.SelectionKey#OP_CONNECT connection establishment success event
java.nio.channels.SelectionKey#OP_ACCEPT has a new connection event
2. Key methods of SelectionKey
public abstract class SelectionKey { public static final int OP_READ = 1; // Read event public static final int OP_WRITE = 4; // Write event public static final int OP_CONNECT = 8; // Link establishment event public static final int OP_ACCEPT = 16; // Request to establish connection event private volatile Object attachment = null; private static final AtomicReferenceFieldUpdater<SelectionKey, Object> attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(SelectionKey.class, Object.class, "attachment"); protected SelectionKey() { } public abstract SelectableChannel channel(); // //Get the channel associated with it public abstract Selector selector(); //Get associated with it Selector object public abstract boolean isValid(); public abstract void cancel(); public abstract int interestOps(); // public abstract SelectionKey interestOps(int var1); ////Set or change listening events public abstract int readyOps(); public final boolean isReadable() { // Whether it is readable, that is, whether to read events return (this.readyOps() & 1) != 0; } public final boolean isWritable() { return (this.readyOps() & 4) != 0; } public final boolean isConnectable() { return (this.readyOps() & 8) != 0; } public final boolean isAcceptable() { return (this.readyOps() & 16) != 0; } public final Object attach(Object var1) { return attachmentUpdater.getAndSet(this, var1); } public final Object attachment() { // //Get the shared data associated with it return this.attachment; } }
3. The key method of serversocketchannel - the core is to establish a connection after connecting
public abstract class ServerSocketChannel extends AbstractSelectableChannel implements NetworkChannel { protected ServerSocketChannel(SelectorProvider var1) { super(var1); } public static ServerSocketChannel open() throws IOException { // Get one ServerSocketChannel passageway return SelectorProvider.provider().openServerSocketChannel(); } public final int validOps() { return 16; } public final ServerSocketChannel bind(SocketAddress var1) throws IOException { // Set server-side slogan return this.bind(var1, 0); } public abstract ServerSocketChannel bind(SocketAddress var1, int var2) throws IOException; public abstract <T> ServerSocketChannel setOption(SocketOption<T> var1, T var2) throws IOException; public abstract ServerSocket socket(); public abstract SocketChannel accept() throws IOException; // Accept a connection and return the channel object representing the connection public abstract SocketAddress getLocalAddress() throws IOException; }
There are also some important methods inherited from the parent class:
java.nio.channels.spi.AbstractSelectableChannel#configureBlocking // Set blocking or non blocking mode, value false Indicates non blocking mode java.nio.channels.SelectableChannel#register(java.nio.channels.Selector, int) // Register a selector and set listening events
4. SocketChannel is the network IO channel, which is specifically responsible for reading and writing operations. NIO writes the data in the buffer to the channel, or reads the data in the channel to the buffer.
public abstract class SocketChannel extends AbstractSelectableChannel implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel { protected SocketChannel(SelectorProvider var1) { super(var1); } public static SocketChannel open() throws IOException { // Open a SocketChannel return SelectorProvider.provider().openSocketChannel(); } public static SocketChannel open(SocketAddress var0) throws IOException { SocketChannel var1 = open(); try { var1.connect(var0); } catch (Throwable var5) { try { var1.close(); } catch (Throwable var4) { var5.addSuppressed(var4); } throw var5; } assert var1.isConnected(); return var1; } public final int validOps() { return 13; } public abstract SocketChannel bind(SocketAddress var1) throws IOException; public abstract <T> SocketChannel setOption(SocketOption<T> var1, T var2) throws IOException; public abstract SocketChannel shutdownInput() throws IOException; public abstract SocketChannel shutdownOutput() throws IOException; public abstract Socket socket(); public abstract boolean isConnected(); public abstract boolean isConnectionPending(); public abstract boolean connect(SocketAddress var1) throws IOException; // //Connect server public abstract boolean finishConnect() throws IOException; // If the above connect Method failed to connect. Next, you need to complete the connection operation through this method public abstract SocketAddress getRemoteAddress() throws IOException; public abstract int read(ByteBuffer var1) throws IOException; //Read data from channel public abstract long read(ByteBuffer[] var1, int var2, int var3) throws IOException; public final long read(ByteBuffer[] var1) throws IOException { return this.read(var1, 0, var1.length); } public abstract int write(ByteBuffer var1) throws IOException; //Write data into the channel public abstract long write(ByteBuffer[] var1, int var2, int var3) throws IOException; public final long write(ByteBuffer[] var1) throws IOException { return this.write(var1, 0, var1.length); } public abstract SocketAddress getLocalAddress() throws IOException; }
There are also some important methods inherited from the parent class:
java.nio.channels.spi.AbstractSelectableChannel#configureBlocking // Set blocking or non blocking mode, value false Indicates non blocking mode java.nio.channels.SelectableChannel#register(java.nio.channels.Selector, int) // Register a selector and set listening events