You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SocketDescriptor.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* Copyright (C) 2012 Brian P. Hinz
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  16. * USA.
  17. */
  18. package com.tigervnc.network;
  19. import java.io.IOException;
  20. import java.net.SocketAddress;
  21. import java.nio.*;
  22. import java.nio.channels.*;
  23. import java.nio.channels.spi.SelectorProvider;
  24. import java.util.Set;
  25. import java.util.Iterator;
  26. import com.tigervnc.rdr.Exception;
  27. public class SocketDescriptor implements FileDescriptor {
  28. public SocketDescriptor() throws Exception {
  29. DefaultSelectorProvider();
  30. try {
  31. channel = SocketChannel.open();
  32. channel.configureBlocking(false);
  33. writeSelector = Selector.open();
  34. readSelector = Selector.open();
  35. } catch (IOException e) {
  36. throw new Exception(e.getMessage());
  37. }
  38. try {
  39. channel.register(writeSelector, SelectionKey.OP_WRITE);
  40. channel.register(readSelector, SelectionKey.OP_READ);
  41. } catch (java.nio.channels.ClosedChannelException e) {
  42. throw new Exception(e.getMessage());
  43. }
  44. }
  45. public void shutdown() throws IOException {
  46. try {
  47. channel.socket().shutdownInput();
  48. channel.socket().shutdownOutput();
  49. } catch(IOException e) {
  50. throw new IOException(e.getMessage());
  51. }
  52. }
  53. public void close() throws IOException {
  54. try {
  55. channel.close();
  56. } catch(IOException e) {
  57. throw new IOException(e.getMessage());
  58. }
  59. }
  60. private static SelectorProvider DefaultSelectorProvider() {
  61. // kqueue() selector provider on OS X is not working, fall back to select() for now
  62. String os = System.getProperty("os.name");
  63. if (os.startsWith("Mac OS X"))
  64. System.setProperty("java.nio.channels.spi.SelectorProvider","sun.nio.ch.PollSelectorProvider");
  65. return SelectorProvider.provider();
  66. }
  67. synchronized public int select(int interestOps, Integer timeout) throws Exception {
  68. int n;
  69. Selector selector;
  70. if ((interestOps & SelectionKey.OP_READ) != 0) {
  71. selector = readSelector;
  72. } else {
  73. selector = writeSelector;
  74. }
  75. selector.selectedKeys().clear();
  76. try {
  77. if (timeout == null) {
  78. n = selector.select();
  79. } else {
  80. int tv = timeout.intValue();
  81. switch(tv) {
  82. case 0:
  83. n = selector.selectNow();
  84. break;
  85. default:
  86. n = selector.select((long)tv);
  87. break;
  88. }
  89. }
  90. } catch (java.io.IOException e) {
  91. throw new Exception(e.getMessage());
  92. }
  93. return n;
  94. }
  95. public int write(ByteBuffer buf, int len) throws Exception {
  96. try {
  97. int n = channel.write((ByteBuffer)buf.slice().limit(len));
  98. buf.position(buf.position()+n);
  99. return n;
  100. } catch (java.io.IOException e) {
  101. throw new Exception(e.getMessage());
  102. }
  103. }
  104. public int read(ByteBuffer buf, int len) throws Exception {
  105. try {
  106. int n = channel.read((ByteBuffer)buf.slice().limit(len));
  107. buf.position(buf.position()+n);
  108. return (n < 0) ? 0 : n;
  109. } catch (java.lang.Exception e) {
  110. throw new Exception(e.getMessage());
  111. }
  112. }
  113. public java.net.Socket socket() {
  114. return channel.socket();
  115. }
  116. public SocketAddress getRemoteAddress() throws IOException {
  117. if (isConnected())
  118. return channel.socket().getRemoteSocketAddress();
  119. return null;
  120. }
  121. public SocketAddress getLocalAddress() throws IOException {
  122. if (isConnected())
  123. return channel.socket().getLocalSocketAddress();
  124. return null;
  125. }
  126. public boolean isConnectionPending() {
  127. return channel.isConnectionPending();
  128. }
  129. public boolean connect(SocketAddress remote) throws IOException {
  130. return channel.connect(remote);
  131. }
  132. public boolean finishConnect() throws IOException {
  133. return channel.finishConnect();
  134. }
  135. public boolean isConnected() {
  136. return channel.isConnected();
  137. }
  138. protected void setChannel(SocketChannel channel_) {
  139. try {
  140. if (channel != null)
  141. channel.close();
  142. if (readSelector != null)
  143. readSelector.close();
  144. if (writeSelector != null)
  145. writeSelector.close();
  146. channel = channel_;
  147. channel.configureBlocking(false);
  148. writeSelector = Selector.open();
  149. readSelector = Selector.open();
  150. } catch (java.io.IOException e) {
  151. throw new Exception(e.getMessage());
  152. }
  153. try {
  154. channel.register(writeSelector, SelectionKey.OP_WRITE);
  155. channel.register(readSelector, SelectionKey.OP_READ);
  156. } catch (java.nio.channels.ClosedChannelException e) {
  157. System.out.println(e.toString());
  158. }
  159. }
  160. protected SocketChannel channel;
  161. protected Selector writeSelector;
  162. protected Selector readSelector;
  163. }