差出人:https : //www.iteye.com/blog/mars914-1238353
Javaでは、TCP / IP + NIOシステム間通信は、java.nio.channelsのChannelおよびSelectorの関連クラスに基づいて実現できます。
システム間通信に使用されます。SocketChannelとServerSocketChannelが使用されます。SocketChannelは、接続の確立、イベントの監視、読み取りおよび書き込み操作に使用されます。ServerSocketChannelは、ポートの監視と接続イベントの監視に使用されます。セレクタを使用して、処理するイベントがあるかどうかを取得できます。
サーバーJavaコード:
- パッケージcom.java.distributed.message.tcpip;
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- 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.nio.charset.Charset;
- パブリック クラスNIOServer {
- / **
- * @param args
- * @throws IOException
- * /
- public static void main(String [] args) はIOException {をスローします
- intポート= 7889;
- //セレクタを開きます
- Selector selector = Selector.open();
- //サーバーソケットチャネルを開きます
- ServerSocketChannel ssc = ServerSocketChannel.open();
- //このチャネルに関連付けられているサーバーソケットを取得します
- ServerSocket serverSocket = ssc.socket();
- // ServerSocketを特定のアドレス(IPアドレスとポート番号)にバインドします
- serverSocket.bind(new InetSocketAddress(port));
- System.out.println("server listen on port:" + port);
- //チャネルのブロッキングモードを調整します
- ssc.configureBlocking(false);
- //このチャネルを指定されたセレクタに登録し、選択キーを返します。SelectionKey.OP_ACCEPT-ソケット受け入れ操作の操作セットビット
- ssc.register(selector、SelectionKey.OP_ACCEPT);
- while(true){
- //タイムアウト:正、チャネルの準備が整うまで最大でmsタイムアウトブロックする;ゼロの場合は無期限にブロックする;負でない必要がある
- int nKeys = selector.select(1000);
- if(nKeys> 0){
- for(SelectionKey key:selector.selectedKeys()){
- / *このキーのチャネルが新しいソケット接続を受け入れる準備ができているかどうかをテストします-
- *このキーのチャネルがソケット受け入れ操作をサポートしていない場合、このメソッドは常にfalseを返します
- * * /
- if(key.isAcceptable()){
- ServerSocketChannel server =(ServerSocketChannel)key.channel();
- SocketChannel sc = server.accept();
- if(sc == null){
- 継続する;
- }
- sc.configureBlocking(false);
- sc.register(selector、SelectionKey.OP_READ);
- } else if(key.isReadable()){
- //新しいバイトバッファを割り当てます
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- SocketChannel sc =(SocketChannel)key.channel();
- int readBytes = 0;
- 文字列message = null;
- 試す{
- int ret;
- 試す{
- while((ret = sc.read(buffer))> 0){
- readBytes + = ret;
- }
- } catch(Exception e){
- readBytes = 0;
- //無視する
- } ようやく{
- //このバッファを逆にします。最初に現在の位置に制限を設定し、次に位置をゼロに設定します
- buffer.flip();
- }
- if(readBytes> 0){
- message = Charset.forName("UTF-8")。decode(buffer).toString();
- buffer = null;
- }
- } ようやく{
- if(buffer!= null)
- buffer.clear();
- }
- if(readBytes> 0){
- System.out.println("クライアントからのメッセージ:" +メッセージ);
- if("quit" .equalsIgnoreCase(message.trim())){
- sc.close();
- selector.close();
- System.out.println("サーバーがシャットダウンされました!");
- System.exit(0);
- }
- String outMessage = "server response:" + message;
- sc.write(Charset.forName("UTF-8")。encode(outMessage));
- }
- }
- }
- selector.selectedKeys()。clear();
- }
- }
- }
- }
クライアントJavaコード:
- パッケージcom.java.distributed.message.tcpip;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.InetSocketAddress;
- import java.net.SocketAddress;
- import java.nio.ByteBuffer;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.SocketChannel;
- import java.nio.charset.Charset;
- パブリック クラスNIOClient {
- / **
- * @param args
- * @throws IOException
- * /
- public static void main(String [] args) はIOException {をスローします
- intポート= 7889;
- SocketChannel channel = SocketChannel.open();
- channel.configureBlocking(false);
- SocketAddress target = new InetSocketAddress("127.0.0.1"、port);
- channel.connect(target);
- Selector selector = Selector.open();
- //ソケット接続操作の操作セットビット
- channel.register(selector、SelectionKey.OP_CONNECT);
- BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in));
- while(true){
- if(channel.isConnected()){
- 文字列command = systemIn.readLine();
- channel.write(Charset.forName("UTF-8")。encode(コマンド));
- if(command == null || "quit" .equalsIgnoreCase(command.trim())){
- systemIn.close();
- channel.close();
- selector.close();
- System.out.println("Client quit!");
- System.exit(0);
- }
- }
- int nKeys = selector.select(1000);
- if(nKeys> 0){
- for(SelectionKey key:selector.selectedKeys()){
- if(key.isConnectable()){
- SocketChannel sc =(SocketChannel)key.channel();
- sc.configureBlocking(false);
- sc.register(selector、SelectionKey.OP_READ);
- sc.finishConnect();
- } else if(key.isReadable()){
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- SocketChannel sc =(SocketChannel)key.channel();
- int readBytes = 0;
- 試す{
- int ret = 0;
- 試す{
- while((ret = sc.read(buffer))> 0){
- バイト= K +を読み取ります。
- }
- } ようやく{
- buffer.flip();
- }
- if(readBytes> 0){
- System.out.println(Charset.forName("UTF-8")
- .decode(buffer).toString());
- buffer = null;
- }
- } ついに{
- if(buffer!= null){
- buffer.clear();
- }
- }
- }
- }
- selector.selectedKeys()。clear();
- }
- }
- }
- }