/src/ibis/smartsockets/plugin/SmartSocket.java

https://github.com/interdroid/smartsockets · Java · 675 lines · 356 code · 143 blank · 176 comment · 99 complexity · 8e2ef4143b211849237407b7761721a3 MD5 · raw file

  1. package ibis.smartsockets.plugin;
  2. import ibis.smartsockets.virtual.VirtualSocket;
  3. import ibis.smartsockets.virtual.VirtualSocketAddress;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. import java.net.InetAddress;
  8. import java.net.InetSocketAddress;
  9. import java.net.Socket;
  10. import java.net.SocketAddress;
  11. import java.net.SocketException;
  12. import java.nio.channels.SocketChannel;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. public class SmartSocket extends Socket {
  16. private VirtualSocket s;
  17. private boolean bound;
  18. private SocketAddress bindpoint;
  19. private Map<String, Object> properties = new HashMap<String, Object>();
  20. private boolean tcpNoDelay = false;
  21. private boolean solinger = false;
  22. private boolean soreuse = false;
  23. private boolean keepalive = false;
  24. private boolean OOBinline = false;
  25. private int linger = 0;
  26. private int timeout = 0;
  27. private int receiveBufferSize = -1;
  28. private int sendBufferSize = -1;
  29. private int trafficClass = -1;
  30. SmartSocket() {
  31. bound = false;
  32. }
  33. SmartSocket(VirtualSocket s) {
  34. this.s = s;
  35. bound = true;
  36. }
  37. /**
  38. * @param bindpoint
  39. * @throws IOException
  40. * @see java.net.Socket#bind(java.net.SocketAddress)
  41. */
  42. public void bind(SocketAddress bindpoint) throws IOException {
  43. if (isClosed()) {
  44. throw new SocketException("Socket is closed");
  45. }
  46. if (isBound()) {
  47. throw new SocketException("Already bound");
  48. }
  49. if (bindpoint == null) {
  50. throw new IllegalArgumentException("Bindpoint is null");
  51. }
  52. if (!(bindpoint instanceof InetSocketAddress ||
  53. bindpoint instanceof VirtualSocketAddress)) {
  54. throw new IllegalArgumentException("Unsupported address type!");
  55. }
  56. // TODO: should check here is the bindpoint is legal ? Problem is that
  57. // it does not necessarily have to result in a real socket....
  58. this.bindpoint = bindpoint;
  59. bound = true;
  60. }
  61. /**
  62. * @throws IOException
  63. * @see java.net.Socket#close()
  64. */
  65. public void close() throws IOException {
  66. if (isClosed()) {
  67. return;
  68. }
  69. if (isConnected()) {
  70. s.close();
  71. }
  72. }
  73. /**
  74. * @param endpoint
  75. * @param timeout
  76. * @throws IOException
  77. * @see java.net.Socket#connect(java.net.SocketAddress, int)
  78. */
  79. public void connect(SocketAddress endpoint, int timeout) throws IOException {
  80. if (isClosed()) {
  81. throw new SocketException("Socket is closed");
  82. }
  83. if (endpoint == null) {
  84. throw new IllegalArgumentException("The target address is null!");
  85. }
  86. if (timeout < 0) {
  87. throw new IllegalArgumentException("Negative timeout");
  88. }
  89. if (isConnected()) {
  90. throw new SocketException("Already connected!");
  91. }
  92. VirtualSocketAddress tmp = null;
  93. if (!(endpoint instanceof VirtualSocketAddress)) {
  94. throw new IllegalArgumentException("Unsupported address type");
  95. }
  96. tmp = (VirtualSocketAddress) endpoint;
  97. s = SmartSocketFactory.getDefault().connect(tmp, timeout, properties);
  98. bound = true;
  99. // No longer used...
  100. properties = null;
  101. }
  102. /**
  103. * @param endpoint
  104. * @throws IOException
  105. * @see java.net.Socket#connect(java.net.SocketAddress)
  106. */
  107. public void connect(SocketAddress endpoint) throws IOException {
  108. connect(endpoint, 0);
  109. }
  110. /**
  111. * @see java.net.Socket#getChannel()
  112. */
  113. public SocketChannel getChannel() {
  114. if (isClosed() || !isConnected()) {
  115. return null;
  116. }
  117. return s.getChannel();
  118. }
  119. /**
  120. * @see java.net.Socket#getInetAddress()
  121. */
  122. public InetAddress getInetAddress() {
  123. if (isClosed() || !isConnected()) {
  124. return null;
  125. }
  126. return s.getInetAddress();
  127. }
  128. /**
  129. * @throws IOException
  130. * @see java.net.Socket#getInputStream()
  131. */
  132. public InputStream getInputStream() throws IOException {
  133. if (isClosed()) {
  134. throw new SocketException("Socket is closed");
  135. }
  136. if (!isConnected()) {
  137. throw new SocketException("Socket is not connected");
  138. }
  139. return s.getInputStream();
  140. }
  141. /**
  142. * @throws SocketException
  143. * @see java.net.Socket#getKeepAlive()
  144. */
  145. public boolean getKeepAlive() throws SocketException {
  146. if (s == null) {
  147. return keepalive;
  148. }
  149. return s.getKeepAlive();
  150. }
  151. /**
  152. * @see java.net.Socket#getLocalAddress()
  153. */
  154. public InetAddress getLocalAddress() {
  155. if (!isBound()) {
  156. return null;
  157. }
  158. if (s != null) {
  159. return s.getLocalAddress();
  160. }
  161. if (bindpoint instanceof InetSocketAddress) {
  162. return ((InetSocketAddress) bindpoint).getAddress();
  163. }
  164. // NOTE: May happen if we are bound to a VirtualSocketAddress.
  165. return null;
  166. }
  167. /**
  168. * @see java.net.Socket#getLocalPort()
  169. */
  170. public int getLocalPort() {
  171. if (!isBound()) {
  172. return -1;
  173. }
  174. if (s != null) {
  175. return s.getLocalPort();
  176. }
  177. if (bindpoint instanceof InetSocketAddress) {
  178. return ((InetSocketAddress) bindpoint).getPort();
  179. }
  180. if (bindpoint instanceof VirtualSocketAddress) {
  181. return ((VirtualSocketAddress) bindpoint).port();
  182. }
  183. // NOTE: Should not happen!
  184. return -1;
  185. }
  186. /**
  187. * @see java.net.Socket#getLocalSocketAddress()
  188. */
  189. public SocketAddress getLocalSocketAddress() {
  190. if (!isBound()) {
  191. return null;
  192. }
  193. if (s != null) {
  194. return s.getLocalSocketAddress();
  195. }
  196. return bindpoint;
  197. }
  198. /**
  199. * @throws SocketException
  200. * @see java.net.Socket#getOOBInline()
  201. */
  202. public boolean getOOBInline() throws SocketException {
  203. if (s == null) {
  204. return OOBinline;
  205. }
  206. return s.getOOBInline();
  207. }
  208. /**
  209. * @throws IOException
  210. * @see java.net.Socket#getOutputStream()
  211. */
  212. public OutputStream getOutputStream() throws IOException {
  213. if (isClosed()) {
  214. throw new SocketException("Socket is closed");
  215. }
  216. if (!isConnected()) {
  217. throw new SocketException("Socket is not connected");
  218. }
  219. return s.getOutputStream();
  220. }
  221. /**
  222. * @see java.net.Socket#getPort()
  223. */
  224. public int getPort() {
  225. if (s == null) {
  226. return 0;
  227. }
  228. return s.getPort();
  229. }
  230. /**
  231. * @throws SocketException
  232. * @see java.net.Socket#getReceiveBufferSize()
  233. */
  234. public int getReceiveBufferSize() throws SocketException {
  235. if (s == null) {
  236. return receiveBufferSize;
  237. }
  238. return s.getReceiveBufferSize();
  239. }
  240. /**
  241. * @see java.net.Socket#getRemoteSocketAddress()
  242. */
  243. public SocketAddress getRemoteSocketAddress() {
  244. if (s == null) {
  245. return null;
  246. }
  247. return s.getRemoteSocketAddress();
  248. }
  249. /**
  250. * @throws SocketException
  251. * @see java.net.Socket#getReuseAddress()
  252. */
  253. public boolean getReuseAddress() throws SocketException {
  254. if (s == null) {
  255. return soreuse;
  256. }
  257. return s.getReuseAddress();
  258. }
  259. /**
  260. * @throws SocketException
  261. * @see java.net.Socket#getSendBufferSize()
  262. */
  263. public int getSendBufferSize() throws SocketException {
  264. if (s == null) {
  265. return sendBufferSize;
  266. }
  267. return s.getSendBufferSize();
  268. }
  269. /**
  270. * @throws SocketException
  271. * @see java.net.Socket#getSoLinger()
  272. */
  273. public int getSoLinger() throws SocketException {
  274. if (s == null) {
  275. if (solinger) {
  276. return linger;
  277. } else {
  278. return -1;
  279. }
  280. }
  281. return s.getSoLinger();
  282. }
  283. /**
  284. * @throws SocketException
  285. * @see java.net.Socket#getSoTimeout()
  286. */
  287. public int getSoTimeout() throws SocketException {
  288. if (s == null) {
  289. return timeout;
  290. }
  291. return s.getSoTimeout();
  292. }
  293. /**
  294. * @throws SocketException
  295. * @see java.net.Socket#getTcpNoDelay()
  296. */
  297. public boolean getTcpNoDelay() throws SocketException {
  298. if (s == null) {
  299. return tcpNoDelay;
  300. }
  301. return s.getTcpNoDelay();
  302. }
  303. /**
  304. * @throws SocketException
  305. * @see java.net.Socket#getTrafficClass()
  306. */
  307. public int getTrafficClass() throws SocketException {
  308. if (s == null) {
  309. return trafficClass;
  310. }
  311. return s.getTrafficClass();
  312. }
  313. /**
  314. * @see java.net.Socket#isBound()
  315. */
  316. public boolean isBound() {
  317. return bound;
  318. }
  319. /**
  320. * @see java.net.Socket#isClosed()
  321. */
  322. public boolean isClosed() {
  323. if (s != null) {
  324. return s.isClosed();
  325. }
  326. // NOTE: When the socket has not been created yet, it isn't closed.
  327. return false;
  328. }
  329. /**
  330. * @see java.net.Socket#isConnected()
  331. */
  332. public boolean isConnected() {
  333. if (s != null) {
  334. return s.isConnected();
  335. }
  336. return false;
  337. }
  338. /**
  339. * @see java.net.Socket#isInputShutdown()
  340. */
  341. public boolean isInputShutdown() {
  342. if (s != null) {
  343. return s.isInputShutdown();
  344. }
  345. return false;
  346. }
  347. /**
  348. * @see java.net.Socket#isOutputShutdown()
  349. */
  350. public boolean isOutputShutdown() {
  351. if (s != null) {
  352. return s.isOutputShutdown();
  353. }
  354. return false;
  355. }
  356. /**
  357. * @param data
  358. * @throws IOException
  359. * @see java.net.Socket#sendUrgentData(int)
  360. */
  361. public void sendUrgentData(int data) throws IOException {
  362. if (isClosed()) {
  363. throw new SocketException("Socket is closed");
  364. }
  365. if (!isConnected()) {
  366. throw new SocketException("Socket is not connected");
  367. }
  368. s.sendUrgentData(data);
  369. }
  370. /**
  371. * @param on
  372. * @throws SocketException
  373. * @see java.net.Socket#setKeepAlive(boolean)
  374. */
  375. public void setKeepAlive(boolean on) throws SocketException {
  376. if (s != null) {
  377. s.setKeepAlive(on);
  378. } else {
  379. properties.put("tcp.keepAlive", on);
  380. }
  381. keepalive = on;
  382. }
  383. /**
  384. * @param on
  385. * @throws SocketException
  386. * @see java.net.Socket#setOOBInline(boolean)
  387. */
  388. public void setOOBInline(boolean on) throws SocketException {
  389. if (s != null) {
  390. s.setOOBInline(on);
  391. } else {
  392. properties.put("tcp.OOBinline", on);
  393. }
  394. OOBinline = on;
  395. }
  396. /**
  397. * @param connectionTime
  398. * @param latency
  399. * @param bandwidth
  400. * @see java.net.Socket#setPerformancePreferences(int, int, int)
  401. */
  402. public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
  403. // TODO: implement!
  404. // s.setPerformancePreferences(connectionTime, latency, bandwidth);
  405. }
  406. /**
  407. * @param size
  408. * @throws SocketException
  409. * @see java.net.Socket#setReceiveBufferSize(int)
  410. */
  411. public void setReceiveBufferSize(int size) throws SocketException {
  412. if (s != null) {
  413. s.setReceiveBufferSize(size);
  414. } else {
  415. properties.put("tcp.receiveBufferSize", size);
  416. }
  417. receiveBufferSize = size;
  418. }
  419. /**
  420. * @param on
  421. * @throws SocketException
  422. * @see java.net.Socket#setReuseAddress(boolean)
  423. */
  424. public void setReuseAddress(boolean on) throws SocketException {
  425. if (s != null) {
  426. s.setReuseAddress(on);
  427. } else {
  428. properties.put("tcp.reuseAddress", on);
  429. }
  430. soreuse = on;
  431. }
  432. /**
  433. * @param size
  434. * @throws SocketException
  435. * @see java.net.Socket#setSendBufferSize(int)
  436. */
  437. public void setSendBufferSize(int size) throws SocketException {
  438. if (s != null) {
  439. s.setSendBufferSize(size);
  440. } else {
  441. properties.put("tcp.sendBufferSize", size);
  442. }
  443. sendBufferSize = size;
  444. }
  445. /**
  446. * @param on
  447. * @param linger
  448. * @throws SocketException
  449. * @see java.net.Socket#setSoLinger(boolean, int)
  450. */
  451. public void setSoLinger(boolean on, int linger) throws SocketException {
  452. if (s != null) {
  453. s.setSoLinger(on, linger);
  454. } else {
  455. properties.put("tcp.linger", linger);
  456. }
  457. this.solinger = on;
  458. this.linger = linger;
  459. }
  460. /**
  461. * @param timeout
  462. * @throws SocketException
  463. * @see java.net.Socket#setSoTimeout(int)
  464. */
  465. public void setSoTimeout(int timeout) throws SocketException {
  466. if (s != null) {
  467. s.setSoTimeout(timeout);
  468. } else {
  469. properties.put("tcp.timeout", timeout);
  470. }
  471. this.timeout = timeout;
  472. }
  473. /**
  474. * @param on
  475. * @throws SocketException
  476. * @see java.net.Socket#setTcpNoDelay(boolean)
  477. */
  478. public void setTcpNoDelay(boolean on) throws SocketException {
  479. if (s != null) {
  480. s.setTcpNoDelay(on);
  481. } else {
  482. properties.put("tcp.nodelay", on);
  483. }
  484. tcpNoDelay = on;
  485. }
  486. /**
  487. * @param tc
  488. * @throws SocketException
  489. * @see java.net.Socket#setTrafficClass(int)
  490. */
  491. public void setTrafficClass(int tc) throws SocketException {
  492. if (s != null) {
  493. s.setTrafficClass(tc);
  494. } else {
  495. properties.put("tcp.trafficClass", tc);
  496. }
  497. trafficClass = tc;
  498. }
  499. /**
  500. * @throws IOException
  501. * @see java.net.Socket#shutdownInput()
  502. */
  503. public void shutdownInput() throws IOException {
  504. if (isClosed()) {
  505. throw new SocketException("Socket is closed");
  506. }
  507. if (!isConnected()) {
  508. throw new SocketException("Socket is not connected");
  509. }
  510. s.shutdownInput();
  511. }
  512. /**
  513. * @throws IOException
  514. * @see java.net.Socket#shutdownOutput()
  515. */
  516. public void shutdownOutput() throws IOException {
  517. if (isClosed()) {
  518. throw new SocketException("Socket is closed");
  519. }
  520. if (!isConnected()) {
  521. throw new SocketException("Socket is not connected");
  522. }
  523. s.shutdownOutput();
  524. }
  525. /**
  526. * @see java.net.Socket#toString()
  527. */
  528. public String toString() {
  529. return "SmartSocket(" + (s == null ? "<not connected>" : s.toString())
  530. + ")";
  531. }
  532. }