History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/nio/ch/SocketAdaptor.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/nio/ch/SocketAdaptor.java+459−0
@@ -0,0 +1,459 @@
1+/*
2+ * Copyright (c) 2000, 2010, 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+
26+package sun.nio.ch;
27+
28+import java.io.*;
29+import java.lang.ref.*;
30+import java.net.*;
31+import java.nio.*;
32+import java.nio.channels.*;
33+import java.security.AccessController;
34+import java.security.PrivilegedExceptionAction;
35+import java.util.*;
36+
37+
38+// Make a socket channel look like a socket.
39+//
40+// The only aspects of java.net.Socket-hood that we don't attempt to emulate
41+// here are the interrupted-I/O exceptions (which our Solaris implementations
42+// attempt to support) and the sending of urgent data. Otherwise an adapted
43+// socket should look enough like a real java.net.Socket to fool most of the
44+// developers most of the time, right down to the exception message strings.
45+//
46+// The methods in this class are defined in exactly the same order as in
47+// java.net.Socket so as to simplify tracking future changes to that class.
48+//
49+
50+public class SocketAdaptor
51+ extends Socket
52+{
53+
54+ // The channel being adapted
55+ private final SocketChannelImpl sc;
56+
57+ // Timeout "option" value for reads
58+ private volatile int timeout = 0;
59+
60+ // ## super will create a useless impl
61+ private SocketAdaptor(SocketChannelImpl sc) {
62+ this.sc = sc;
63+ }
64+
65+ public static Socket create(SocketChannelImpl sc) {
66+ return new SocketAdaptor(sc);
67+ }
68+
69+ public SocketChannel getChannel() {
70+ return sc;
71+ }
72+
73+ // Override this method just to protect against changes in the superclass
74+ //
75+ public void connect(SocketAddress remote) throws IOException {
76+ connect(remote, 0);
77+ }
78+
79+ public void connect(SocketAddress remote, int timeout) throws IOException {
80+ if (remote == null)
81+ throw new IllegalArgumentException("connect: The address can't be null");
82+ if (timeout < 0)
83+ throw new IllegalArgumentException("connect: timeout can't be negative");
84+
85+ synchronized (sc.blockingLock()) {
86+ if (!sc.isBlocking())
87+ throw new IllegalBlockingModeException();
88+
89+ try {
90+
91+ if (timeout == 0) {
92+ sc.connect(remote);
93+ return;
94+ }
95+
96+ // Implement timeout with a selector
97+ SelectionKey sk = null;
98+ Selector sel = null;
99+ sc.configureBlocking(false);
100+ try {
101+ if (sc.connect(remote))
102+ return;
103+ sel = Util.getTemporarySelector(sc);
104+ sk = sc.register(sel, SelectionKey.OP_CONNECT);
105+ long to = timeout;
106+ for (;;) {
107+ if (!sc.isOpen())
108+ throw new ClosedChannelException();
109+ long st = System.currentTimeMillis();
110+ int ns = sel.select(to);
111+ if (ns > 0 &&
112+ sk.isConnectable() && sc.finishConnect())
113+ break;
114+ sel.selectedKeys().remove(sk);
115+ to -= System.currentTimeMillis() - st;
116+ if (to <= 0) {
117+ try {
118+ sc.close();
119+ } catch (IOException x) { }
120+ throw new SocketTimeoutException();
121+ }
122+ }
123+ } finally {
124+ if (sk != null)
125+ sk.cancel();
126+ if (sc.isOpen())
127+ sc.configureBlocking(true);
128+ if (sel != null)
129+ Util.releaseTemporarySelector(sel);
130+ }
131+
132+ } catch (Exception x) {
133+ Net.translateException(x, true);
134+ }
135+ }
136+
137+ }
138+
139+ public void bind(SocketAddress local) throws IOException {
140+ try {
141+ sc.bind(local);
142+ } catch (Exception x) {
143+ Net.translateException(x);
144+ }
145+ }
146+
147+ public InetAddress getInetAddress() {
148+ SocketAddress remote = sc.remoteAddress();
149+ if (remote == null) {
150+ return null;
151+ } else {
152+ return ((InetSocketAddress)remote).getAddress();
153+ }
154+ }
155+
156+ public InetAddress getLocalAddress() {
157+ if (sc.isOpen()) {
158+ SocketAddress local = sc.localAddress();
159+ if (local != null)
160+ return ((InetSocketAddress)local).getAddress();
161+ }
162+ return new InetSocketAddress(0).getAddress();
163+ }
164+
165+ public int getPort() {
166+ SocketAddress remote = sc.remoteAddress();
167+ if (remote == null) {
168+ return 0;
169+ } else {
170+ return ((InetSocketAddress)remote).getPort();
171+ }
172+ }
173+
174+ public int getLocalPort() {
175+ SocketAddress local = sc.localAddress();
176+ if (local == null) {
177+ return -1;
178+ } else {
179+ return ((InetSocketAddress)local).getPort();
180+ }
181+ }
182+
183+ private class SocketInputStream
184+ extends ChannelInputStream
185+ {
186+ private SocketInputStream() {
187+ super(sc);
188+ }
189+
190+ protected int read(ByteBuffer bb)
191+ throws IOException
192+ {
193+ synchronized (sc.blockingLock()) {
194+ if (!sc.isBlocking())
195+ throw new IllegalBlockingModeException();
196+ if (timeout == 0)
197+ return sc.read(bb);
198+
199+ // Implement timeout with a selector
200+ SelectionKey sk = null;
201+ Selector sel = null;
202+ sc.configureBlocking(false);
203+ try {
204+ int n;
205+ if ((n = sc.read(bb)) != 0)
206+ return n;
207+ sel = Util.getTemporarySelector(sc);
208+ sk = sc.register(sel, SelectionKey.OP_READ);
209+ long to = timeout;
210+ for (;;) {
211+ if (!sc.isOpen())
212+ throw new ClosedChannelException();
213+ long st = System.currentTimeMillis();
214+ int ns = sel.select(to);
215+ if (ns > 0 && sk.isReadable()) {
216+ if ((n = sc.read(bb)) != 0)
217+ return n;
218+ }
219+ sel.selectedKeys().remove(sk);
220+ to -= System.currentTimeMillis() - st;
221+ if (to <= 0)
222+ throw new SocketTimeoutException();
223+ }
224+ } finally {
225+ if (sk != null)
226+ sk.cancel();
227+ if (sc.isOpen())
228+ sc.configureBlocking(true);
229+ if (sel != null)
230+ Util.releaseTemporarySelector(sel);
231+ }
232+
233+ }
234+ }
235+ }
236+
237+ private InputStream socketInputStream = null;
238+
239+ public InputStream getInputStream() throws IOException {
240+ if (!sc.isOpen())
241+ throw new SocketException("Socket is closed");
242+ if (!sc.isConnected())
243+ throw new SocketException("Socket is not connected");
244+ if (!sc.isInputOpen())
245+ throw new SocketException("Socket input is shutdown");
246+ if (socketInputStream == null) {
247+ try {
248+ socketInputStream = AccessController.doPrivileged(
249+ new PrivilegedExceptionAction<InputStream>() {
250+ public InputStream run() throws IOException {
251+ return new SocketInputStream();
252+ }
253+ });
254+ } catch (java.security.PrivilegedActionException e) {
255+ throw (IOException)e.getException();
256+ }
257+ }
258+ return socketInputStream;
259+ }
260+
261+ public OutputStream getOutputStream() throws IOException {
262+ if (!sc.isOpen())
263+ throw new SocketException("Socket is closed");
264+ if (!sc.isConnected())
265+ throw new SocketException("Socket is not connected");
266+ if (!sc.isOutputOpen())
267+ throw new SocketException("Socket output is shutdown");
268+ OutputStream os = null;
269+ try {
270+ os = AccessController.doPrivileged(
271+ new PrivilegedExceptionAction<OutputStream>() {
272+ public OutputStream run() throws IOException {
273+ return Channels.newOutputStream(sc);
274+ }
275+ });
276+ } catch (java.security.PrivilegedActionException e) {
277+ throw (IOException)e.getException();
278+ }
279+ return os;
280+ }
281+
282+ private void setBooleanOption(SocketOption<Boolean> name, boolean value)
283+ throws SocketException
284+ {
285+ try {
286+ sc.setOption(name, value);
287+ } catch (IOException x) {
288+ Net.translateToSocketException(x);
289+ }
290+ }
291+
292+ private void setIntOption(SocketOption<Integer> name, int value)
293+ throws SocketException
294+ {
295+ try {
296+ sc.setOption(name, value);
297+ } catch (IOException x) {
298+ Net.translateToSocketException(x);
299+ }
300+ }
301+
302+ private boolean getBooleanOption(SocketOption<Boolean> name) throws SocketException {
303+ try {
304+ return sc.getOption(name).booleanValue();
305+ } catch (IOException x) {
306+ Net.translateToSocketException(x);
307+ return false; // keep compiler happy
308+ }
309+ }
310+
311+ private int getIntOption(SocketOption<Integer> name) throws SocketException {
312+ try {
313+ return sc.getOption(name).intValue();
314+ } catch (IOException x) {
315+ Net.translateToSocketException(x);
316+ return -1; // keep compiler happy
317+ }
318+ }
319+
320+ public void setTcpNoDelay(boolean on) throws SocketException {
321+ setBooleanOption(StandardSocketOptions.TCP_NODELAY, on);
322+ }
323+
324+ public boolean getTcpNoDelay() throws SocketException {
325+ return getBooleanOption(StandardSocketOptions.TCP_NODELAY);
326+ }
327+
328+ public void setSoLinger(boolean on, int linger) throws SocketException {
329+ if (!on)
330+ linger = -1;
331+ setIntOption(StandardSocketOptions.SO_LINGER, linger);
332+ }
333+
334+ public int getSoLinger() throws SocketException {
335+ return getIntOption(StandardSocketOptions.SO_LINGER);
336+ }
337+
338+ public void sendUrgentData(int data) throws IOException {
339+ synchronized (sc.blockingLock()) {
340+ if (!sc.isBlocking())
341+ throw new IllegalBlockingModeException();
342+ int n = sc.sendOutOfBandData((byte)data);
343+ assert n == 1;
344+ }
345+ }
346+
347+ public void setOOBInline(boolean on) throws SocketException {
348+ setBooleanOption(ExtendedSocketOption.SO_OOBINLINE, on);
349+ }
350+
351+ public boolean getOOBInline() throws SocketException {
352+ return getBooleanOption(ExtendedSocketOption.SO_OOBINLINE);
353+ }
354+
355+ public void setSoTimeout(int timeout) throws SocketException {
356+ if (timeout < 0)
357+ throw new IllegalArgumentException("timeout can't be negative");
358+ this.timeout = timeout;
359+ }
360+
361+ public int getSoTimeout() throws SocketException {
362+ return timeout;
363+ }
364+
365+ public void setSendBufferSize(int size) throws SocketException {
366+ // size 0 valid for SocketChannel, invalid for Socket
367+ if (size <= 0)
368+ throw new IllegalArgumentException("Invalid send size");
369+ setIntOption(StandardSocketOptions.SO_SNDBUF, size);
370+ }
371+
372+ public int getSendBufferSize() throws SocketException {
373+ return getIntOption(StandardSocketOptions.SO_SNDBUF);
374+ }
375+
376+ public void setReceiveBufferSize(int size) throws SocketException {
377+ // size 0 valid for SocketChannel, invalid for Socket
378+ if (size <= 0)
379+ throw new IllegalArgumentException("Invalid receive size");
380+ setIntOption(StandardSocketOptions.SO_RCVBUF, size);
381+ }
382+
383+ public int getReceiveBufferSize() throws SocketException {
384+ return getIntOption(StandardSocketOptions.SO_RCVBUF);
385+ }
386+
387+ public void setKeepAlive(boolean on) throws SocketException {
388+ setBooleanOption(StandardSocketOptions.SO_KEEPALIVE, on);
389+ }
390+
391+ public boolean getKeepAlive() throws SocketException {
392+ return getBooleanOption(StandardSocketOptions.SO_KEEPALIVE);
393+ }
394+
395+ public void setTrafficClass(int tc) throws SocketException {
396+ setIntOption(StandardSocketOptions.IP_TOS, tc);
397+ }
398+
399+ public int getTrafficClass() throws SocketException {
400+ return getIntOption(StandardSocketOptions.IP_TOS);
401+ }
402+
403+ public void setReuseAddress(boolean on) throws SocketException {
404+ setBooleanOption(StandardSocketOptions.SO_REUSEADDR, on);
405+ }
406+
407+ public boolean getReuseAddress() throws SocketException {
408+ return getBooleanOption(StandardSocketOptions.SO_REUSEADDR);
409+ }
410+
411+ public void close() throws IOException {
412+ sc.close();
413+ }
414+
415+ public void shutdownInput() throws IOException {
416+ try {
417+ sc.shutdownInput();
418+ } catch (Exception x) {
419+ Net.translateException(x);
420+ }
421+ }
422+
423+ public void shutdownOutput() throws IOException {
424+ try {
425+ sc.shutdownOutput();
426+ } catch (Exception x) {
427+ Net.translateException(x);
428+ }
429+ }
430+
431+ public String toString() {
432+ if (sc.isConnected())
433+ return "Socket[addr=" + getInetAddress() +
434+ ",port=" + getPort() +
435+ ",localport=" + getLocalPort() + "]";
436+ return "Socket[unconnected]";
437+ }
438+
439+ public boolean isConnected() {
440+ return sc.isConnected();
441+ }
442+
443+ public boolean isBound() {
444+ return sc.localAddress() != null;
445+ }
446+
447+ public boolean isClosed() {
448+ return !sc.isOpen();
449+ }
450+
451+ public boolean isInputShutdown() {
452+ return !sc.isInputOpen();
453+ }
454+
455+ public boolean isOutputShutdown() {
456+ return !sc.isOutputOpen();
457+ }
458+
459+}