Java NIO (Non-blocking I/O) dengan Server-Client Contoh – java.nio.ByteBuffer dan channels.Selector – Java NIO Vs. saya
Diterbitkan: 2021-08-06
Java NIO
adalah topik favorit saya. Saya telah bekerja dengan NIO sejak 2 tahun terakhir dan ingin berbagi Server-Client code
sederhana untuk pembaca saya yang bebas menggunakan kode ini di lingkungan produksi mereka.
Mulai JDK 1.4, NIO dibuat untuk memungkinkan semua pemrogram Java mengimplementasikan input/output berkecepatan sangat tinggi tanpa harus berurusan dengan kode asli khusus. NIO menggunakan pustaka java.nio.buffer
dibandingkan dengan I/O sederhana yang menguras dan mengisi kembali buffer secara internal sistem operasi apa pun.
Dalam tutorial ini kita akan membahas pustaka java.nio.channels
dan java.nio.channels.Selector
.
-
channels
mewakili koneksi ke entitas yang mampu melakukan operasi I/O, seperti file dan soket; mendefinisikan pemilih , untuk operasi I/O multipleks dan non-pemblokiran. -
selector
dapat dibuat dengan menerapkanopen method
kelas ini, yang akan menggunakan penyedia pemilih default sistem untuk membuat pemilih baru.

Jika Anda memiliki below questions
ini maka Anda berada di tempat yang tepat:
- Bagaimana memulai dengan Java NIO
- Apa itu tutorial Java NIO dan Java NIO
- NIO Java asinkron
- Apa kegunaan sebenarnya dari paket java nio?
- Tutorial Java NIO
- Bagaimana menerapkan I/O Berkinerja Tinggi dengan Java NIO
Mari kita mulai:
Langkah 1
- Buat
CrunchifyNIOServer.java
yang membuka koneksi padaport 1111
- gunakan
isAcceptable()
untuk memeriksa apakah saluran siap menerima koneksi soket baru- Jika ya – sambungkan
- gunakan
isReadable()
untuk memeriksa apakah saluran siap dibaca- jika ya – baca dari buffer dan cetak di konsol Eclipse
- Setelah Anda mendapatkan nama perusahaan terakhir "crunchify"
- hubungan dekat
Langkah 2
- Buat
CrunchifyNIOClient.java
yang mencoba terhubung ke server padaport 1111
- Buat ArrayList dengan 5 nama perusahaan
- Ulangi melalui ArrayList dan kirim setiap nama perusahaan ke server
- Tutup koneksi setelah tugas selesai
Lihatlah Kode Java ini:
Kode Server – CrunchifyNIOServer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
package crunchify . com . tutorials ; 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 . Iterator ; import java . util . Set ; /** * @author Crunchify.com * Java NIO (Non-blocking I/O) with Server-Client Example - java.nio.ByteBuffer and channels.Selector * This is CrunchifyNIOServer.java */ public class CrunchifyNIOServer { @ SuppressWarnings ( "unused" ) public static void main ( String [ ] args ) throws IOException { // Selector: A multiplexor of SelectableChannel objects. // A selector may be created by invoking the open method of this class, which will use the system's default selector provider to create a new selector. // A selector may also be created by invoking the openSelector method of a custom selector provider. A selector remains open until it is closed via its close method. Selector selector = Selector . open ( ) ; // selector is open here // ServerSocketChannel: A selectable channel for stream-oriented listening sockets. // A server-socket channel is created by invoking the open method of this class. // It is not possible to create a channel for an arbitrary, pre-existing ServerSocket. ServerSocketChannel crunchifySocket = ServerSocketChannel . open ( ) ; // InetSocketAddress: This class implements an IP Socket Address (IP address + port number) It can also be a pair (hostname + port number), // in which case an attempt will be made to resolve the hostname. // If resolution fails then the address is said to be unresolved but can still be used on some circumstances like connecting through a proxy. InetSocketAddress crunchifyAddr = new InetSocketAddress ( "localhost" , 1111 ) ; // Binds the channel's socket to a local address and configures the socket to listen for connections crunchifySocket . bind ( crunchifyAddr ) ; // Adjusts this channel's blocking mode. crunchifySocket . configureBlocking ( false ) ; int ops = crunchifySocket . validOps ( ) ; // SelectionKey: A token representing the registration of a SelectableChannel with a Selector. // A selection key is created each time a channel is registered with a selector. // A key remains valid until it is cancelled by invoking its cancel method, by closing its channel, or by closing its selector. SelectionKey selectKy = crunchifySocket . register ( selector , ops , null ) ; // Infinite loop.. // Keep server running while ( true ) { log ( "I'm a server and I'm waiting for new connection and buffer select..." ) ; // Selects a set of keys whose corresponding channels are ready for I/O operations selector . select ( ) ; // token representing the registration of a SelectableChannel with a Selector Set < SelectionKey > crunchifyKeys = selector . selectedKeys ( ) ; Iterator < SelectionKey > crunchifyIterator = crunchifyKeys . iterator ( ) ; while ( crunchifyIterator . hasNext ( ) ) { SelectionKey myKey = crunchifyIterator . next ( ) ; // Tests whether this key's channel is ready to accept a new socket connection if ( myKey . isAcceptable ( ) ) { SocketChannel crunchifyClient = crunchifySocket . accept ( ) ; // Adjusts this channel's blocking mode to false crunchifyClient . configureBlocking ( false ) ; // Operation-set bit for read operations crunchifyClient . register ( selector , SelectionKey . OP_READ ) ; log ( "Connection Accepted: " + crunchifyClient . getLocalAddress ( ) + "\n" ) ; // Tests whether this key's channel is ready for reading } else if ( myKey . isReadable ( ) ) { SocketChannel crunchifyClient = ( SocketChannel ) myKey . channel ( ) ; // ByteBuffer: A byte buffer. // This class defines six categories of operations upon byte buffers: // Absolute and relative get and put methods that read and write single bytes; // Absolute and relative bulk get methods that transfer contiguous sequences of bytes from this buffer into an array; ByteBuffer crunchifyBuffer = ByteBuffer . allocate ( 256 ) ; crunchifyClient . read ( crunchifyBuffer ) ; String result = new String ( crunchifyBuffer . array ( ) ) . trim ( ) ; log ( "Message received: " + result ) ; if ( result . equals ( "Crunchify.com" ) ) { crunchifyClient . close ( ) ; log ( "\nIt's time to close connection as we got last company name 'Crunchify'" ) ; log ( "\nServer will keep running. Try running client again to establish new connection" ) ; } } crunchifyIterator . remove ( ) ; } } } private static void log ( String str ) { System . out . println ( str ) ; } } |
Kode Klien – CrunchifyNIOClient.java

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
package crunchify . com . tutorials ; import java . io . IOException ; import java . net . InetSocketAddress ; import java . nio . ByteBuffer ; import java . nio . channels . SocketChannel ; import java . util . ArrayList ; /** * @author Crunchify.com * Java NIO (Non-blocking I/O) with Server-Client Example - java.nio.ByteBuffer and channels.Selector * This is CrunchifyNIOClient.java */ public class CrunchifyNIOClient { public static void main ( String [ ] args ) throws IOException , InterruptedException { InetSocketAddress crunchifyAddr = new InetSocketAddress ( "localhost" , 1111 ) ; // selectable channel for stream-oriented connecting sockets SocketChannel crunchifyClient = SocketChannel . open ( crunchifyAddr ) ; log ( "Connecting to Server on port 1111..." ) ; ArrayList <String> companyDetails = new ArrayList <String> ( ) ; // create a ArrayList with companyName list companyDetails . add ( "Facebook" ) ; companyDetails . add ( "Twitter" ) ; companyDetails . add ( "IBM" ) ; companyDetails . add ( "Google" ) ; companyDetails . add ( "Crunchify" ) ; for ( String companyName : companyDetails ) { byte [ ] message = new String ( companyName ) . getBytes ( ) ; ByteBuffer buffer = ByteBuffer . wrap ( message ) ; crunchifyClient . write ( buffer ) ; log ( "sending: " + companyName ) ; buffer . clear ( ) ; // wait for 2 seconds before sending next message Thread . sleep ( 2000 ) ; } // close(): Closes this channel. // If the channel has already been closed then this method returns immediately. // Otherwise it marks the channel as closed and then invokes the implCloseChannel method in order to complete the close operation. crunchifyClient . close ( ) ; } private static void log ( String str ) { System . out . println ( str ) ; } } |
Hasil di Sisi Server:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
I 'm a server and I' m waiting for new connection and buffer select . . . Connection Accepted : / 127.0.0.1 : 1111 I 'm a server and <meta charset="utf-8"/>I' m waiting for new connection and buffer select . . . Message received : Facebook < meta charset = "utf-8" / > I 'm a server and <meta charset="utf-8"/>I' m waiting for new connection and buffer select . . . Message received : Twitter < meta charset = "utf-8" / > I 'm a server and <meta charset="utf-8"/>I' m waiting for new connection and buffer select . . . Message received : IBM < meta charset = "utf-8" / > I 'm a server and <meta charset="utf-8"/>I' m waiting for new connection and < a href = "https://crunchify.com/how-to-remove-duplicate-elements-from-csv-or-any-other-file-in-java/" target = "_blank" rel = "noreferrer noopener" > buffer < / a > select . . . Message received : Google < meta charset = "utf-8" / > I 'm a server and <meta charset="utf-8"/>I' m waiting for new connection and buffer select . . . Message received : Crunchify It 's time to <a href="https://crunchify.com/json-manipulation-in-java-examples/" target="_blank" rel="noreferrer noopener">close connection</a> as we got last company name ' Crunchify ' Server will keep running. Try running client again to establish new connection <meta charset="utf-8"/>I' m a server and < meta charset = "utf-8" / > I ' m waiting for new connection and buffer select . . . |
Hasil di Sisi Klien:
1 2 3 4 5 6 |
Connecting to Server on port 1111... sending : Facebook sending : Twitter sending : IBM sending : Google sending : Crunchify |
Beberapa FAQ:
- Dari klien, bagaimana cara mempertahankan koneksi yang persisten?
- Anda bisa menggunakan
socket.setKeepAlive(true);
untuk memiliki koneksi hidup dari sisi klien.
- Anda bisa menggunakan
- Bagaimana cara membaca tanggapan atas pesan yang saya kirim ke server. Server terus menghasilkan pesan setiap 10 detik. Saya hanya perlu membaca tanggapan atas permintaan saya. Dari apa yang saya pahami, TCP "mengalirkan" data alih-alih catatan akhir, dll.
- Untuk komunikasi server klien, protokol perlu didefinisikan dengan baik. panggilan
readLine()
akan diblokir sampai semua data dikembalikan, jadi jangan gunakan itu.Try reading bytes from the stream until -1 is returned.
- Untuk komunikasi server klien, protokol perlu didefinisikan dengan baik. panggilan
Beri tahu saya jika itu berhasil.
