概要
java.nioを用いてAndroidで動作するTCPクライアントを作成しています。
nioのセレクタ、チャンネルの仕組みについて理解できない部分があったため質問致しました。
質問
下記ソースにおける、key.isWritableはどのような場合にtrueになるのでしょうか。
ドキュメントも見たのですが、
対応するチャネルが「書き込み可能な状態」になっているか、次の書き込みができるようにリモートシャットダウンされているか、エラーによって一時停止していることを検出する
となっており、恥ずかしながらどういった状態が「書き込み可能な状態」であるのか理解できませんでした。
よろしくお願いいたします。
ソース
Java
1import java.io.IOException; 2import java.net.ConnectException; 3import java.net.InetSocketAddress; 4import java.nio.ByteBuffer; 5import java.nio.channels.SelectionKey; 6import java.nio.channels.Selector; 7import java.nio.channels.SocketChannel; 8import java.nio.charset.Charset; 9import java.util.Arrays; 10import java.util.Iterator; 11import java.util.concurrent.Executors; 12 13public class TCPClientForUnity{ 14 15 private SocketChannel mSocketChannel; 16 private Selector mSelector; 17 private ByteBuffer mReadBuffer; 18 private ByteBuffer mWriteBuffer; 19 private String mAddress; 20 private int mPort; 21 22 public TCPClientForUnity(final String adr, final int PORT){ 23 mAddress = adr; 24 mPort = PORT; 25 } 26 27 public void CreateBuffer(final int size){ 28 mReadBuffer = ByteBuffer.allocate(size); 29 mWriteBuffer = ByteBuffer.allocate(size); 30 } 31 32 public void CreateSocketChannel(final String adr, final int PORT){ 33 try { 34 mSelector = Selector.open(); 35 mSocketChannel = SocketChannel.open(); 36 mSocketChannel.configureBlocking(false); 37 mSocketChannel.connect(new InetSocketAddress(adr, PORT)); 38 mSocketChannel.register(mSelector, SelectionKey.OP_CONNECT); 39 }catch(IOException e){ 40 e.printStackTrace(); 41 } 42 } 43 44 private final Runnable mAcceptTask = new Runnable() { 45 public void run() { 46 System.out.println("start runnnable"); 47 CreateBuffer(1024); 48 49 try { //IOException 50 51 while (!Thread.interrupted()) { 52 try { //ConnectException 53 54 CreateSocketChannel(mAddress, mPort); 55 while (!Thread.interrupted() & mSocketChannel.isOpen()) { 56 mSelector.select(); 57 Iterator<SelectionKey> keys = mSelector.selectedKeys().iterator(); 58 59 while (keys.hasNext()) { 60 SelectionKey key = keys.next(); 61 keys.remove(); 62 63 if (key.isConnectable()) { 64 System.out.println("connecting..."); 65 mSocketChannel.finishConnect(); // if connection fail, throw ConnectException 66 System.out.println("CLIENT: Connected"); 67 mSocketChannel.register(mSelector, SelectionKey.OP_WRITE, mWriteBuffer); 68 mSocketChannel.register(mSelector, SelectionKey.OP_READ, mReadBuffer); 69 } 70 71 if (key.isWritable()) { 72 ByteBuffer writeBuf = (ByteBuffer) key.attachment(); 73 mSocketChannel.write(writeBuf); 74 if (!mWriteBuffer.hasRemaining()) { 75 System.out.println("CLIENT: Write " + Arrays.toString(mWriteBuffer.array())); 76 } 77 } 78 79 if (key.isReadable()) { 80 ByteBuffer readBuf = (ByteBuffer) key.attachment(); 81 mSocketChannel.read(readBuf); 82 if (!readBuf.hasRemaining()) { 83 String msg = Arrays.toString(readBuf.array()); 84 System.out.println("CLIENT: Read " + msg); 85 SendToRaspi(msg); 86 } 87 //mSocketChannel.close(); 88 //break loop; 89 } 90 } 91 } 92 } catch (ConnectException e) { 93 e.getStackTrace(); 94 try{ 95 Thread.sleep(100); 96 }catch (InterruptedException e2){ 97 e2.getStackTrace(); 98 } 99 } 100 } 101 }catch (IOException e) { 102 103 } 104 } 105 }; 106 107 public void SendToUnity(String msg){ 108 System.out.println("in TCPClientForUnity, msg: " + msg); 109 mWriteBuffer.put(msg.getBytes(Charset.forName("UTF-8"))); 110 } 111 112 public void SendToRaspi(String msg){ 113 System.out.println("plz over write"); 114 } 115 116 public void start() { 117 Executors.newSingleThreadExecutor().execute(mAcceptTask); 118 } 119 120}
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/19 08:50