PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/library/java/net/AbstractPlainDatagramSocketImpl.java

https://bitbucket.org/chancey/z
Java | 352 lines | 192 code | 39 blank | 121 comment | 40 complexity | af7118bcc6ce735e026112b353446ce1 MD5 | raw file
  1. /*
  2. * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * This code is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 only, as
  7. * published by the Free Software Foundation. Oracle designates this
  8. * particular file as subject to the "Classpath" exception as provided
  9. * by Oracle in the LICENSE file that accompanied this code.
  10. *
  11. * This code is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. * version 2 for more details (a copy is included in the LICENSE file that
  15. * accompanied this code).
  16. *
  17. * You should have received a copy of the GNU General Public License version
  18. * 2 along with this work; if not, write to the Free Software Foundation,
  19. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22. * or visit www.oracle.com if you need additional information or have any
  23. * questions.
  24. */
  25. package java.net;
  26. import java.io.FileDescriptor;
  27. import java.io.IOException;
  28. import java.io.InterruptedIOException;
  29. import java.util.Enumeration;
  30. import sun.net.ResourceManager;
  31. /**
  32. * Abstract datagram and multicast socket implementation base class.
  33. * Note: This is not a public class, so that applets cannot call
  34. * into the implementation directly and hence cannot bypass the
  35. * security checks present in the DatagramSocket and MulticastSocket
  36. * classes.
  37. *
  38. * @author Pavani Diwanji
  39. */
  40. abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
  41. {
  42. /* timeout value for receive() */
  43. int timeout = 0;
  44. boolean connected = false;
  45. private int trafficClass = 0;
  46. private InetAddress connectedAddress = null;
  47. private int connectedPort = -1;
  48. /* cached socket options */
  49. private int multicastInterface = 0;
  50. private boolean loopbackMode = true;
  51. private int ttl = -1;
  52. /**
  53. * Load net library into runtime.
  54. */
  55. static {
  56. java.security.AccessController.doPrivileged(
  57. new sun.security.action.LoadLibraryAction("net"));
  58. }
  59. /**
  60. * Creates a datagram socket
  61. */
  62. protected synchronized void create() throws SocketException {
  63. ResourceManager.beforeUdpCreate();
  64. fd = new FileDescriptor();
  65. try {
  66. datagramSocketCreate();
  67. } catch (SocketException ioe) {
  68. ResourceManager.afterUdpClose();
  69. fd = null;
  70. throw ioe;
  71. }
  72. }
  73. /**
  74. * Binds a datagram socket to a local port.
  75. */
  76. protected synchronized void bind(int lport, InetAddress laddr)
  77. throws SocketException {
  78. bind0(lport, laddr);
  79. }
  80. protected abstract void bind0(int lport, InetAddress laddr)
  81. throws SocketException;
  82. /**
  83. * Sends a datagram packet. The packet contains the data and the
  84. * destination address to send the packet to.
  85. * @param packet to be sent.
  86. */
  87. protected abstract void send(DatagramPacket p) throws IOException;
  88. /**
  89. * Connects a datagram socket to a remote destination. This associates the remote
  90. * address with the local socket so that datagrams may only be sent to this destination
  91. * and received from this destination.
  92. * @param address the remote InetAddress to connect to
  93. * @param port the remote port number
  94. */
  95. protected void connect(InetAddress address, int port) throws SocketException {
  96. connect0(address, port);
  97. connectedAddress = address;
  98. connectedPort = port;
  99. connected = true;
  100. }
  101. /**
  102. * Disconnects a previously connected socket. Does nothing if the socket was
  103. * not connected already.
  104. */
  105. protected void disconnect() {
  106. disconnect0(connectedAddress.family);
  107. connected = false;
  108. connectedAddress = null;
  109. connectedPort = -1;
  110. }
  111. /**
  112. * Peek at the packet to see who it is from.
  113. * @param return the address which the packet came from.
  114. */
  115. protected abstract int peek(InetAddress i) throws IOException;
  116. protected abstract int peekData(DatagramPacket p) throws IOException;
  117. /**
  118. * Receive the datagram packet.
  119. * @param Packet Received.
  120. */
  121. protected synchronized void receive(DatagramPacket p)
  122. throws IOException {
  123. receive0(p);
  124. }
  125. protected abstract void receive0(DatagramPacket p)
  126. throws IOException;
  127. /**
  128. * Set the TTL (time-to-live) option.
  129. * @param TTL to be set.
  130. */
  131. protected abstract void setTimeToLive(int ttl) throws IOException;
  132. /**
  133. * Get the TTL (time-to-live) option.
  134. */
  135. protected abstract int getTimeToLive() throws IOException;
  136. /**
  137. * Set the TTL (time-to-live) option.
  138. * @param TTL to be set.
  139. */
  140. protected abstract void setTTL(byte ttl) throws IOException;
  141. /**
  142. * Get the TTL (time-to-live) option.
  143. */
  144. protected abstract byte getTTL() throws IOException;
  145. /**
  146. * Join the multicast group.
  147. * @param multicast address to join.
  148. */
  149. protected void join(InetAddress inetaddr) throws IOException {
  150. join(inetaddr, null);
  151. }
  152. /**
  153. * Leave the multicast group.
  154. * @param multicast address to leave.
  155. */
  156. protected void leave(InetAddress inetaddr) throws IOException {
  157. leave(inetaddr, null);
  158. }
  159. /**
  160. * Join the multicast group.
  161. * @param multicast address to join.
  162. * @param netIf specifies the local interface to receive multicast
  163. * datagram packets
  164. * @throws IllegalArgumentException if mcastaddr is null or is a
  165. * SocketAddress subclass not supported by this socket
  166. * @since 1.4
  167. */
  168. protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
  169. throws IOException {
  170. if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
  171. throw new IllegalArgumentException("Unsupported address type");
  172. join(((InetSocketAddress)mcastaddr).getAddress(), netIf);
  173. }
  174. protected abstract void join(InetAddress inetaddr, NetworkInterface netIf)
  175. throws IOException;
  176. /**
  177. * Leave the multicast group.
  178. * @param multicast address to leave.
  179. * @param netIf specified the local interface to leave the group at
  180. * @throws IllegalArgumentException if mcastaddr is null or is a
  181. * SocketAddress subclass not supported by this socket
  182. * @since 1.4
  183. */
  184. protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
  185. throws IOException {
  186. if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
  187. throw new IllegalArgumentException("Unsupported address type");
  188. leave(((InetSocketAddress)mcastaddr).getAddress(), netIf);
  189. }
  190. protected abstract void leave(InetAddress inetaddr, NetworkInterface netIf)
  191. throws IOException;
  192. /**
  193. * Close the socket.
  194. */
  195. protected void close() {
  196. if (fd != null) {
  197. datagramSocketClose();
  198. ResourceManager.afterUdpClose();
  199. fd = null;
  200. }
  201. }
  202. protected boolean isClosed() {
  203. return (fd == null) ? true : false;
  204. }
  205. protected void finalize() {
  206. close();
  207. }
  208. /**
  209. * set a value - since we only support (setting) binary options
  210. * here, o must be a Boolean
  211. */
  212. public void setOption(int optID, Object o) throws SocketException {
  213. if (isClosed()) {
  214. throw new SocketException("Socket Closed");
  215. }
  216. switch (optID) {
  217. /* check type safety b4 going native. These should never
  218. * fail, since only java.Socket* has access to
  219. * PlainSocketImpl.setOption().
  220. */
  221. case SO_TIMEOUT:
  222. if (o == null || !(o instanceof Integer)) {
  223. throw new SocketException("bad argument for SO_TIMEOUT");
  224. }
  225. int tmp = ((Integer) o).intValue();
  226. if (tmp < 0)
  227. throw new IllegalArgumentException("timeout < 0");
  228. timeout = tmp;
  229. return;
  230. case IP_TOS:
  231. if (o == null || !(o instanceof Integer)) {
  232. throw new SocketException("bad argument for IP_TOS");
  233. }
  234. trafficClass = ((Integer)o).intValue();
  235. break;
  236. case SO_REUSEADDR:
  237. if (o == null || !(o instanceof Boolean)) {
  238. throw new SocketException("bad argument for SO_REUSEADDR");
  239. }
  240. break;
  241. case SO_BROADCAST:
  242. if (o == null || !(o instanceof Boolean)) {
  243. throw new SocketException("bad argument for SO_BROADCAST");
  244. }
  245. break;
  246. case SO_BINDADDR:
  247. throw new SocketException("Cannot re-bind Socket");
  248. case SO_RCVBUF:
  249. case SO_SNDBUF:
  250. if (o == null || !(o instanceof Integer) ||
  251. ((Integer)o).intValue() < 0) {
  252. throw new SocketException("bad argument for SO_SNDBUF or " +
  253. "SO_RCVBUF");
  254. }
  255. break;
  256. case IP_MULTICAST_IF:
  257. if (o == null || !(o instanceof InetAddress))
  258. throw new SocketException("bad argument for IP_MULTICAST_IF");
  259. break;
  260. case IP_MULTICAST_IF2:
  261. if (o == null || !(o instanceof NetworkInterface))
  262. throw new SocketException("bad argument for IP_MULTICAST_IF2");
  263. break;
  264. case IP_MULTICAST_LOOP:
  265. if (o == null || !(o instanceof Boolean))
  266. throw new SocketException("bad argument for IP_MULTICAST_LOOP");
  267. break;
  268. default:
  269. throw new SocketException("invalid option: " + optID);
  270. }
  271. socketSetOption(optID, o);
  272. }
  273. /*
  274. * get option's state - set or not
  275. */
  276. public Object getOption(int optID) throws SocketException {
  277. if (isClosed()) {
  278. throw new SocketException("Socket Closed");
  279. }
  280. Object result;
  281. switch (optID) {
  282. case SO_TIMEOUT:
  283. result = new Integer(timeout);
  284. break;
  285. case IP_TOS:
  286. result = socketGetOption(optID);
  287. if ( ((Integer)result).intValue() == -1) {
  288. result = new Integer(trafficClass);
  289. }
  290. break;
  291. case SO_BINDADDR:
  292. case IP_MULTICAST_IF:
  293. case IP_MULTICAST_IF2:
  294. case SO_RCVBUF:
  295. case SO_SNDBUF:
  296. case IP_MULTICAST_LOOP:
  297. case SO_REUSEADDR:
  298. case SO_BROADCAST:
  299. result = socketGetOption(optID);
  300. break;
  301. default:
  302. throw new SocketException("invalid option: " + optID);
  303. }
  304. return result;
  305. }
  306. protected abstract void datagramSocketCreate() throws SocketException;
  307. protected abstract void datagramSocketClose();
  308. protected abstract void socketSetOption(int opt, Object val)
  309. throws SocketException;
  310. protected abstract Object socketGetOption(int opt) throws SocketException;
  311. protected abstract void connect0(InetAddress address, int port) throws SocketException;
  312. protected abstract void disconnect0(int family);
  313. }