/src/ibis/smartsockets/virtual/VirtualSocket.java

https://github.com/interdroid/smartsockets · Java · 599 lines · 219 code · 60 blank · 320 comment · 0 complexity · e1e8ebf72c2fc30b51a5e08e3218c5c0 MD5 · raw file

  1. package ibis.smartsockets.virtual;
  2. import ibis.smartsockets.direct.DirectSocketAddress;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.OutputStream;
  6. import java.net.InetAddress;
  7. import java.net.SocketAddress;
  8. import java.net.SocketException;
  9. import java.nio.channels.SocketChannel;
  10. import java.util.Map;
  11. /**
  12. * This is the base class for various Virtual Socket implementations.
  13. *
  14. *
  15. */
  16. public abstract class VirtualSocket {
  17. /** The remote address connected to. */
  18. protected DirectSocketAddress remote;
  19. /** The remote port connected to. */
  20. protected int remotePort;
  21. /** The configuration of this VirtualSocket. */
  22. protected Map<String, Object> props;
  23. /**
  24. * Create an unbound VirtualSocket.
  25. */
  26. protected VirtualSocket() {
  27. }
  28. /**
  29. * Create a VirtualSocket connected to a remote address.
  30. * @param target the address to bind to.
  31. */
  32. protected VirtualSocket(VirtualSocketAddress target) {
  33. this.remote = target.machine();
  34. this.remotePort = target.port();
  35. }
  36. /**
  37. * Returns the address of the remote endpoint this socket is connected to,
  38. * or null if it is unconnected.
  39. *
  40. * @return the address of the remote endpoint.
  41. */
  42. public SocketAddress getRemoteSocketAddress() {
  43. return remote;
  44. }
  45. /**
  46. * Returns the remote port to which this socket is connected.
  47. *
  48. * @return the remote port number to which this socket is connected, or 0
  49. * if the socket is not connected yet.
  50. */
  51. public int getPort() {
  52. return remotePort;
  53. }
  54. /**
  55. * Returns the number of bytes written to this VirtualSocket.
  56. *
  57. * @return the number of bytes written.
  58. * @throws IOException if the number of bytes written cannot be retrieved.
  59. */
  60. public long getBytesWritten() throws IOException {
  61. System.err.println("getBytesWritten() not implemented by " + this);
  62. throw new RuntimeException("getBytesWritten() not implemented by "
  63. + this);
  64. }
  65. /**
  66. * Returns the number of bytes read from this VirtualSocket.
  67. *
  68. * @return the number of bytes read.
  69. * @throws IOException if the number of bytes read cannot be retrieved.
  70. */
  71. public long getBytesRead() throws IOException {
  72. System.err.println("getBytesRead() not implemented by " + this);
  73. throw new RuntimeException("getBytesRead() not implemented by " + this);
  74. }
  75. /**
  76. * Closes this socket.
  77. *
  78. * Once a socket has been closed, it is not available for further networking
  79. * use (i.e. can't be reconnected or rebound). A new socket needs to be
  80. * created.
  81. * <p>
  82. * Closing this socket will also close the socket's InputStream and
  83. * OutputStream.
  84. * <p>
  85. * If this socket has an associated channel then the channel is closed as
  86. * well.
  87. *
  88. * @throws IOException if an I/O error occurs when closing this socket.
  89. */
  90. public void close() throws IOException {
  91. System.err.println("close() not implemented by " + this);
  92. throw new RuntimeException("close() not implemented by " + this);
  93. }
  94. /**
  95. * Returns the unique SocketChannel object associated with this socket, if
  96. * any.
  97. *
  98. * @return the socket channel associated with this socket, or null if it is
  99. * not available.
  100. */
  101. public SocketChannel getChannel() {
  102. System.err.println("getChannel() not implemented by " + this);
  103. throw new RuntimeException("getChannel() not implemented by " + this);
  104. }
  105. /**
  106. * Returns an input stream for this socket.
  107. *
  108. * @return an input stream for reading bytes from this socket.
  109. * @throws IOException if an I/O error occurs when creating the input
  110. * stream,the socket is closed or the socket is not connected.
  111. */
  112. public InputStream getInputStream() throws IOException {
  113. System.err.println("getInputStream() not implemented by " + this);
  114. throw new RuntimeException("getInputStream() not implemented by "
  115. + this);
  116. }
  117. /**
  118. * Tests if SO_KEEPALIVE is enabled.
  119. *
  120. * @return if SO_KEEPALIVE is enabled.
  121. * @throws SocketException the test count not be performed.
  122. */
  123. public boolean getKeepAlive() throws SocketException {
  124. System.err.println("getKeepAlive() not implemented by " + this);
  125. throw new RuntimeException("getKeepAlive() not implemented by " + this);
  126. }
  127. /**
  128. * Returns the local port to which this socket is bound.
  129. *
  130. * @return the local port number to which this socket is bound or -1 if
  131. * the socket is not bound yet.
  132. */
  133. public int getLocalPort() {
  134. System.err.println("getLocalPort() not implemented by " + this);
  135. throw new RuntimeException("getLocalPort() not implemented by " + this);
  136. }
  137. /**
  138. * Returns the address which this socket is bound to, or null if it is not
  139. * bound yet.
  140. *
  141. * @return SocketAddress representing the local endpoint of this socket, or
  142. * null if it is not bound yet.
  143. */
  144. public SocketAddress getLocalSocketAddress() {
  145. System.err.println("getLocalSocketAddress() not implemented by "+ this);
  146. throw new RuntimeException(
  147. "getLocalSocketAddress() not implemented by " + this);
  148. }
  149. /**
  150. * Tests if OOBINLINE is enabled.
  151. *
  152. * @return if OOBINLINE is enabled.
  153. * @throws SocketException if the test failed.
  154. */
  155. public boolean getOOBInline() throws SocketException {
  156. System.err.println("getOOBInline() not implemented by " + this);
  157. throw new RuntimeException("getOOBInline() not implemented by " + this);
  158. }
  159. /**
  160. * Returns an output stream for this socket.
  161. *
  162. * @return an output stream for writing bytes to this socket.
  163. * @throws IOException if an I/O error occurs when creating the output
  164. * stream or if the socket is not connected.
  165. */
  166. public OutputStream getOutputStream() throws IOException {
  167. System.err.println("getOutputStream() not implemented by " + this);
  168. throw new RuntimeException("getOutputStream() not implemented by "
  169. + this);
  170. }
  171. /**
  172. * Gets the value of the SO_RCVBUF option for this Socket (the receive
  173. * buffer size).
  174. *
  175. * @return the value of the SO_RCVBUF option for this Socket.
  176. * @throws SocketException if there is an error in retrieving SO_RCVBUF.
  177. */
  178. public int getReceiveBufferSize() throws SocketException {
  179. System.err.println("getReceiveBufferSize() not implemented by " + this);
  180. throw new RuntimeException("getReceiveBufferSize() not implemented by "
  181. + this);
  182. }
  183. /**
  184. * Tests if SO_REUSEADDR is enabled.
  185. *
  186. * @return if SO_REUSEADDR is enabled.
  187. * @throws SocketException if the test failed.
  188. */
  189. public boolean getReuseAddress() throws SocketException {
  190. System.err.println("getReuseAddress() not implemented by " + this);
  191. throw new RuntimeException("getReuseAddress() not implemented by "
  192. + this);
  193. }
  194. /**
  195. * Gets the value of the SO_SNDBUF option for this Socket (the send
  196. * buffer size).
  197. *
  198. * @return the value of the SO_SNDBUF option for this Socket.
  199. * @throws SocketException if there is an error in retrieving SO_SNDBUF.
  200. */
  201. public int getSendBufferSize() throws SocketException {
  202. System.err.println("getSendBufferSize() not implemented by " + this);
  203. throw new RuntimeException("getSendBufferSize() not implemented by "
  204. + this);
  205. }
  206. /**
  207. * Returns setting for SO_LINGER. -1 returns implies that the option is
  208. * disabled. The setting only affects socket close.
  209. *
  210. * @return the setting for SO_LINGER.
  211. * @throws SocketException if there is an error in retrieving SO_LINGER.
  212. */
  213. public int getSoLinger() throws SocketException {
  214. System.err.println("getSoLinger() not implemented by " + this);
  215. throw new RuntimeException("getSoLinger() not implemented by " + this);
  216. }
  217. /**
  218. * Returns setting for SO_TIMEOUT. 0 returns implies that the option is
  219. * disabled (i.e., timeout of infinity).
  220. *
  221. * @return the value of SO_TIMEOUT.
  222. * @throws SocketException if there is an error in retrieving SO_TIMEOUT.
  223. */
  224. public int getSoTimeout() throws SocketException {
  225. System.err.println("getSoTimeout() not implemented by " + this);
  226. throw new RuntimeException("getSoTimeout() not implemented by " + this);
  227. }
  228. /**
  229. * Tests if TCP_NODELAY is enabled.
  230. *
  231. * @return if TCP_NODELAY is enabled.
  232. * @throws SocketException if there is an error in retrieving TCP_NODELAY.
  233. */
  234. public boolean getTcpNoDelay() throws SocketException {
  235. System.err.println("getTcpNoDelay() not implemented by " + this);
  236. throw new RuntimeException("getTcpNoDelay() not implemented by "+ this);
  237. }
  238. /**
  239. * Gets traffic class for packets sent from this Socket.
  240. *
  241. * @return the traffic class set.
  242. * @throws SocketException if there is an error in retrieving the traffic
  243. * class.
  244. */
  245. public int getTrafficClass() throws SocketException {
  246. System.err.println("getTrafficClass() not implemented by " + this);
  247. throw new RuntimeException("getTrafficClass() not implemented by "
  248. + this);
  249. }
  250. /**
  251. * Returns if this socket is bound.
  252. *
  253. * @return if the socket is bound.
  254. */
  255. public boolean isBound() {
  256. System.err.println("isBound() not implemented by " + this);
  257. throw new RuntimeException("isBound() not implemented by " + this);
  258. }
  259. /**
  260. * Returns if this socket is closed.
  261. *
  262. * @return if the socket is closed.
  263. */
  264. public boolean isClosed() {
  265. System.err.println("isClosed() not implemented by " + this);
  266. throw new RuntimeException("isClosed() not implemented by " + this);
  267. }
  268. /**
  269. * Returns if this socket is connected.
  270. *
  271. * @return if the socket is connected.
  272. */
  273. public boolean isConnected() {
  274. System.err.println("isConnected() not implemented by " + this);
  275. throw new RuntimeException("isConnected() not implemented by " + this);
  276. }
  277. /**
  278. * Returns if the input of this socket is shut down.
  279. *
  280. * @return if the input of this socket is shut down.
  281. */
  282. public boolean isInputShutdown() {
  283. System.err.println("isInputShutdown() not implemented by " + this);
  284. throw new RuntimeException("isInputShutdown() not implemented by "
  285. + this);
  286. }
  287. /**
  288. * Returns if the output of this socket is shut down.
  289. *
  290. * @return if the output of this socket is shut down.
  291. */
  292. public boolean isOutputShutdown() {
  293. System.err.println("isOutputShutdown() not implemented by " + this);
  294. throw new RuntimeException("isOutputShutdown() not implemented by "
  295. + this);
  296. }
  297. /**
  298. * Send one byte of urgent data on the socket.
  299. * @param data the byte to send (only the lowest 8 bits are used).
  300. * @throws IOException if there is an error in sending the data.
  301. */
  302. public void sendUrgentData(int data) throws IOException {
  303. System.err.println("sendUrgentData(int) not implemented by " + this);
  304. throw new RuntimeException("sendUrgentData(int) not implemented by "
  305. + this);
  306. }
  307. /**
  308. * Enable/disable SO_KEEPALIVE.
  309. *
  310. * @param on should SO_KEEPALIVE be turned on ?
  311. * @throws SocketException if an error occurred setting SO_KEEPALIVE.
  312. */
  313. public void setKeepAlive(boolean on) throws SocketException {
  314. System.err.println("setKeepAlive(boolean) not implemented by " + this);
  315. throw new RuntimeException("setKeepAlive(boolean) not implemented by "
  316. + this);
  317. }
  318. /**
  319. * Enable/disable SO_OOBINLINE.
  320. *
  321. * @param on should SO_OOBINLINE be turned on ?
  322. * @throws SocketException if an error occurred setting SO_OOBINLINE.
  323. */
  324. public void setOOBInline(boolean on) throws SocketException {
  325. System.err.println("setOOBInline(boolean) not implemented by " + this);
  326. throw new RuntimeException("setOOBInline(boolean) not implemented by "
  327. + this);
  328. }
  329. /**
  330. * Set the value of SO_RCVBUF (the receive buffer size). This is only a hint
  331. * to the underlying implementation, and the value may be ignored or
  332. * altered.
  333. *
  334. * @param sz the suggested size of SO_RCVBUF.
  335. * @throws SocketException if an error occurred setting SO_RCVBUF.
  336. */
  337. public void setReceiveBufferSize(int sz) throws SocketException {
  338. System.err.println("setReceiveBufferSize(int) not implemented by "
  339. + this);
  340. throw new RuntimeException(
  341. "setReceiveBufferSize(int) not implemented by " + this);
  342. }
  343. /**
  344. * Enable/disable SO_REUSEADDR.
  345. *
  346. * @param on should SO_REUSEADDR be turned on ?
  347. * @throws SocketException if an error occurred setting SO_REUSEADDR.
  348. */
  349. public void setReuseAddress(boolean on) throws SocketException {
  350. System.err.println("setReuseAddress(boolean) not implemented by "
  351. + this);
  352. throw new RuntimeException(
  353. "setReuseAddress(boolean) not implemented by " + this);
  354. }
  355. /**
  356. * Set the value of SO_SNDBUF (the send buffer size). This is only a hint
  357. * to the underlying implementation, and the value may be ignored or
  358. * altered.
  359. *
  360. * @param sz the suggested size of SO_SNDBUF.
  361. * @throws SocketException if an error occurred setting SO_SNDBUF.
  362. */
  363. public void setSendBufferSize(int sz) throws SocketException {
  364. System.err.println("setSendBufferSize(int) not implemented by " + this);
  365. throw new RuntimeException("setSendBufferSize(int) not implemented by "
  366. + this);
  367. }
  368. /**
  369. * Enable/disable SO_LINGER with the specified linger time in seconds.
  370. *
  371. * @param on should SO_LINGER be turned on ?
  372. * @param linger linger time in seconds.
  373. * @throws SocketException if an error occurred setting SO_LINGER.
  374. */
  375. public void setSoLinger(boolean on, int linger) throws SocketException {
  376. System.err.println("setSoLinger(boolean, int) not implemented by "
  377. + this);
  378. throw new RuntimeException(
  379. "setSoLinger(boolean, int) not implemented by " + this);
  380. }
  381. /**
  382. * Set SO_TIMEOUT with the specified timeout, in milliseconds.
  383. * A value of zero is interpreted as an infinite timeout. Negative values
  384. * are not allowed.
  385. *
  386. * @param t the timeout, in milliseconds.
  387. * @throws SocketException if an error occurred setting SO_TIMEOUT.
  388. */
  389. public void setSoTimeout(int t) throws SocketException {
  390. System.err.println("setSoTimeout(int) not implemented by " + this);
  391. throw new RuntimeException("setSoTimeout(int) not implemented by "
  392. + this);
  393. }
  394. /**
  395. * Enable/disable TCP_NODELAY.
  396. *
  397. * @param on should TCP_NODELAY be turned on ?
  398. * @throws SocketException if an error occurred setting TCP_NODELAY.
  399. */
  400. public void setTcpNoDelay(boolean on) throws SocketException {
  401. System.err.println("setTcpNoDelay(boolean) not implemented by " + this);
  402. throw new RuntimeException("setTcpNoDelay(boolean) not implemented by "
  403. + this);
  404. }
  405. /**
  406. * Set traffic class of the IP packets.
  407. *
  408. * @param tc the traffic class.
  409. * @throws SocketException if an error occurred setting TCP_NODELAY.
  410. */
  411. public void setTrafficClass(int tc) throws SocketException {
  412. System.err.println("setTrafficClass(int) not implemented by " + this);
  413. throw new RuntimeException("setTrafficClass(int) not implemented by "
  414. + this);
  415. }
  416. /**
  417. * Shutdown the input of the Socket by placing it at end-of-stream.
  418. *
  419. * Any further data received will be discarded.
  420. *
  421. * @throws IOException if an I/O error occurs when shutting down the input.
  422. */
  423. public void shutdownInput() throws IOException {
  424. System.err.println("shutdownInput() not implemented by " + this);
  425. throw new RuntimeException("shutdownInput() not implemented by "+ this);
  426. }
  427. /**
  428. * Flush any written data and shutdown the output of the Socket.
  429. *
  430. * Any further data writes on the socket will result in an IOException.
  431. *
  432. * @throws IOException if an I/O error occurs when shutting down the output.
  433. */
  434. public void shutdownOutput() throws IOException {
  435. System.err.println("shutdownOutput() not implemented by " + this);
  436. throw new RuntimeException("shutdownOutput() not implemented by "
  437. + this);
  438. }
  439. /**
  440. * Sets performance preferences for this socket.
  441. *
  442. * @param connectionTime relative importance of a short connection time.
  443. * @param latency relative importance of a short latency.
  444. * @param bandwidth relative importance of a high bandwidth.
  445. */
  446. public void setPerformancePreferences(int connectionTime, int latency,
  447. int bandwidth) {
  448. System.err.println("setPerformancePreferences() not implemented by "
  449. + this);
  450. throw new RuntimeException("shutdownOutput() not implemented by "
  451. + this);
  452. }
  453. /**
  454. * {@inheritDoc}
  455. */
  456. @Override
  457. public String toString() {
  458. return "unimplemented toString()!";
  459. }
  460. /**
  461. * Returns the properties associated with this socket.
  462. *
  463. * @return a map containing implementation-specific properties of this
  464. * socket.
  465. */
  466. public Map<String, Object> properties() {
  467. return props;
  468. }
  469. /**
  470. * Sets a number of properties of this socket.
  471. *
  472. * Allows the user to set implementation-specific properties of this socket.
  473. *
  474. * @param properties map containing the properties to set.
  475. *
  476. */
  477. public void setProperties(Map<String, Object> properties) {
  478. // TODO: Add instead of overwrite ?
  479. props = properties;
  480. }
  481. /**
  482. * Returns the value associated with a specific property of this socket.
  483. *
  484. * @param key name of the property whose value should be returned
  485. * @return value associated with the property, or null if the property does
  486. * not exist.
  487. */
  488. public Object getProperty(String key) {
  489. return props.get(key);
  490. }
  491. /**
  492. * Sets a property of this socket.
  493. *
  494. * @param key name of the property to set.
  495. * @param val new value of the property.
  496. */
  497. public void setProperty(String key, Object val) {
  498. props.put(key, val);
  499. }
  500. /**
  501. * Wait for a specified timeout for the target to accept a connection from
  502. * this socket.
  503. *
  504. * @param timeout the timeout in milliseconds.
  505. * @throws IOException if the connection failed to be created.
  506. */
  507. public abstract void waitForAccept(int timeout) throws IOException;
  508. /**
  509. * Accept this connection.
  510. *
  511. * @param timeout the time allocated for the accept.
  512. * @throws IOException the accept failed.
  513. */
  514. protected abstract void connectionAccepted(int timeout) throws IOException;
  515. /**
  516. * Reject this connection.
  517. *
  518. * @param timeout the time allocated for the reject.
  519. */
  520. protected abstract void connectionRejected(int timeout);
  521. /**
  522. * DO NOT USE!
  523. *
  524. * @return always null
  525. */
  526. public InetAddress getLocalAddress() {
  527. // NOTE: Can never be implemented correctly ?
  528. return null;
  529. }
  530. /**
  531. * DO NOT USE!
  532. *
  533. * @return always null
  534. */
  535. public InetAddress getInetAddress() {
  536. // NOTE: Can never be implemented correctly ?
  537. return null;
  538. }
  539. }