Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / net / Socket.java
blob5d32237691832b863e6b3805e9e9b9b8a980059c
1 /* Socket.java -- Client socket implementation
2 Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA.
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
39 package java.net;
41 import gnu.java.net.PlainSocketImpl;
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.io.OutputStream;
46 import java.nio.channels.IllegalBlockingModeException;
47 import java.nio.channels.SocketChannel;
50 /* Written using on-line Java Platform 1.2 API Specification.
51 * Status: I believe all methods are implemented.
54 /**
55 * This class models a client site socket. A socket is a TCP/IP endpoint
56 * for network communications conceptually similar to a file handle.
57 * <p>
58 * This class does not actually do any work. Instead, it redirects all of
59 * its calls to a socket implementation object which implements the
60 * <code>SocketImpl</code> interface. The implementation class is
61 * instantiated by factory class that implements the
62 * <code>SocketImplFactory interface</code>. A default
63 * factory is provided, however the factory may be set by a call to
64 * the <code>setSocketImplFactory</code> method. Note that this may only be
65 * done once per virtual machine. If a subsequent attempt is made to set the
66 * factory, a <code>SocketException</code> will be thrown.
68 * @author Aaron M. Renn (arenn@urbanophile.com)
69 * @author Per Bothner (bothner@cygnus.com)
71 public class Socket
73 /**
74 * This is the user SocketImplFactory for this class. If this variable is
75 * null, a default factory is used.
77 static SocketImplFactory factory;
79 /**
80 * The implementation object to which calls are redirected
82 // package-private because ServerSocket.implAccept() needs to access it.
83 SocketImpl impl;
85 /**
86 * True if socket implementation was created by calling their
87 * create() method.
89 // package-private because ServerSocket.implAccept() needs to access it.
90 boolean implCreated;
92 /**
93 * True if the socket is bound.
95 private boolean bound;
97 /**
98 * True if input is shutdown.
100 private boolean inputShutdown;
103 * True if output is shutdown.
105 private boolean outputShutdown;
108 * Initializes a new instance of <code>Socket</code> object without
109 * connecting to a remote host. This useful for subclasses of socket that
110 * might want this behavior.
112 * @specnote This constructor is public since JDK 1.4
113 * @since 1.1
115 public Socket()
117 if (factory != null)
118 impl = factory.createSocketImpl();
119 else
120 impl = new PlainSocketImpl();
124 * Initializes a new instance of <code>Socket</code> object without
125 * connecting to a remote host. This is useful for subclasses of socket
126 * that might want this behavior.
127 * <p>
128 * Additionally, this socket will be created using the supplied
129 * implementation class instead the default class or one returned by a
130 * factory. If this value is <code>null</code>, the default Socket
131 * implementation is used.
133 * @param impl The <code>SocketImpl</code> to use for this
134 * <code>Socket</code>
136 * @exception SocketException If an error occurs
138 * @since 1.1
140 protected Socket(SocketImpl impl) throws SocketException
142 if (impl == null)
143 this.impl = new PlainSocketImpl();
144 else
145 this.impl = impl;
149 * Initializes a new instance of <code>Socket</code> and connects to the
150 * hostname and port specified as arguments.
152 * @param host The name of the host to connect to
153 * @param port The port number to connect to
155 * @exception UnknownHostException If the hostname cannot be resolved to a
156 * network address.
157 * @exception IOException If an error occurs
158 * @exception SecurityException If a security manager exists and its
159 * checkConnect method doesn't allow the operation
161 public Socket(String host, int port)
162 throws UnknownHostException, IOException
164 this(InetAddress.getByName(host), port, null, 0, true);
168 * Initializes a new instance of <code>Socket</code> and connects to the
169 * address and port number specified as arguments.
171 * @param address The address to connect to
172 * @param port The port number to connect to
174 * @exception IOException If an error occurs
175 * @exception SecurityException If a security manager exists and its
176 * checkConnect method doesn't allow the operation
178 public Socket(InetAddress address, int port) throws IOException
180 this(address, port, null, 0, true);
184 * Initializes a new instance of <code>Socket</code> that connects to the
185 * named host on the specified port and binds to the specified local address
186 * and port.
188 * @param host The name of the remote host to connect to.
189 * @param port The remote port to connect to.
190 * @param localAddr The local address to bind to.
191 * @param localPort The local port to bind to.
193 * @exception SecurityException If the <code>SecurityManager</code>
194 * exists and does not allow a connection to the specified host/port or
195 * binding to the specified local host/port.
196 * @exception IOException If a connection error occurs.
198 * @since 1.1
200 public Socket(String host, int port, InetAddress localAddr, int localPort)
201 throws IOException
203 this(InetAddress.getByName(host), port, localAddr, localPort, true);
207 * Initializes a new instance of <code>Socket</code> and connects to the
208 * address and port number specified as arguments, plus binds to the
209 * specified local address and port.
211 * @param address The remote address to connect to
212 * @param port The remote port to connect to
213 * @param localAddr The local address to connect to
214 * @param localPort The local port to connect to
216 * @exception IOException If an error occurs
217 * @exception SecurityException If a security manager exists and its
218 * checkConnect method doesn't allow the operation
220 * @since 1.1
222 public Socket(InetAddress address, int port, InetAddress localAddr,
223 int localPort) throws IOException
225 this(address, port, localAddr, localPort, true);
229 * Initializes a new instance of <code>Socket</code> and connects to the
230 * hostname and port specified as arguments. If the stream argument is set
231 * to <code>true</code>, then a stream socket is created. If it is
232 * <code>false</code>, a datagram socket is created.
234 * @param host The name of the host to connect to
235 * @param port The port to connect to
236 * @param stream <code>true</code> for a stream socket, <code>false</code>
237 * for a datagram socket
239 * @exception IOException If an error occurs
240 * @exception SecurityException If a security manager exists and its
241 * checkConnect method doesn't allow the operation
243 * @deprecated Use the <code>DatagramSocket</code> class to create
244 * datagram oriented sockets.
246 public Socket(String host, int port, boolean stream)
247 throws IOException
249 this(InetAddress.getByName(host), port, null, 0, stream);
253 * Initializes a new instance of <code>Socket</code> and connects to the
254 * address and port number specified as arguments. If the stream param is
255 * <code>true</code>, a stream socket will be created, otherwise a datagram
256 * socket is created.
258 * @param host The address to connect to
259 * @param port The port number to connect to
260 * @param stream <code>true</code> to create a stream socket,
261 * <code>false</code> to create a datagram socket.
263 * @exception IOException If an error occurs
264 * @exception SecurityException If a security manager exists and its
265 * checkConnect method doesn't allow the operation
267 * @deprecated Use the <code>DatagramSocket</code> class to create
268 * datagram oriented sockets.
270 public Socket(InetAddress host, int port, boolean stream)
271 throws IOException
273 this(host, port, null, 0, stream);
277 * This constructor is where the real work takes place. Connect to the
278 * specified address and port. Use default local values if not specified,
279 * otherwise use the local host and port passed in. Create as stream or
280 * datagram based on "stream" argument.
281 * <p>
283 * @param raddr The remote address to connect to
284 * @param rport The remote port to connect to
285 * @param laddr The local address to connect to
286 * @param lport The local port to connect to
287 * @param stream true for a stream socket, false for a datagram socket
289 * @exception IOException If an error occurs
290 * @exception SecurityException If a security manager exists and its
291 * checkConnect method doesn't allow the operation
293 private Socket(InetAddress raddr, int rport, InetAddress laddr, int lport,
294 boolean stream) throws IOException
296 this();
298 SecurityManager sm = System.getSecurityManager();
299 if (sm != null)
300 sm.checkConnect(raddr.getHostName(), rport);
302 // bind socket
303 SocketAddress bindaddr =
304 laddr == null ? null : new InetSocketAddress(laddr, lport);
305 bind(bindaddr);
307 // connect socket
308 connect(new InetSocketAddress(raddr, rport));
310 // FIXME: JCL p. 1586 says if localPort is unspecified, bind to any port,
311 // i.e. '0' and if localAddr is unspecified, use getLocalAddress() as
312 // that default. JDK 1.2 doc infers not to do a bind.
315 private SocketImpl getImpl() throws SocketException
319 if (! implCreated)
321 impl.create(true);
322 implCreated = true;
325 catch (IOException e)
327 throw new SocketException(e.getMessage());
330 return impl;
334 * Binds the socket to the givent local address/port
336 * @param bindpoint The address/port to bind to
338 * @exception IOException If an error occurs
339 * @exception SecurityException If a security manager exists and its
340 * checkConnect method doesn't allow the operation
341 * @exception IllegalArgumentException If the address type is not supported
343 * @since 1.4
345 public void bind(SocketAddress bindpoint) throws IOException
347 if (isClosed())
348 throw new SocketException("socket is closed");
350 // XXX: JDK 1.4.1 API documentation says that if bindpoint is null the
351 // socket will be bound to an ephemeral port and a valid local address.
352 if (bindpoint == null)
353 bindpoint = new InetSocketAddress(InetAddress.ANY_IF, 0);
355 if (! (bindpoint instanceof InetSocketAddress))
356 throw new IllegalArgumentException();
358 InetSocketAddress tmp = (InetSocketAddress) bindpoint;
360 // bind to address/port
363 getImpl().bind(tmp.getAddress(), tmp.getPort());
364 bound = true;
366 catch (IOException exception)
368 close();
369 throw exception;
371 catch (RuntimeException exception)
373 close();
374 throw exception;
376 catch (Error error)
378 close();
379 throw error;
384 * Connects the socket with a remote address.
386 * @param endpoint The address to connect to
388 * @exception IOException If an error occurs
389 * @exception IllegalArgumentException If the addess type is not supported
390 * @exception IllegalBlockingModeException If this socket has an associated
391 * channel, and the channel is in non-blocking mode
393 * @since 1.4
395 public void connect(SocketAddress endpoint) throws IOException
397 connect(endpoint, 0);
401 * Connects the socket with a remote address. A timeout of zero is
402 * interpreted as an infinite timeout. The connection will then block
403 * until established or an error occurs.
405 * @param endpoint The address to connect to
406 * @param timeout The length of the timeout in milliseconds, or
407 * 0 to indicate no timeout.
409 * @exception IOException If an error occurs
410 * @exception IllegalArgumentException If the address type is not supported
411 * @exception IllegalBlockingModeException If this socket has an associated
412 * channel, and the channel is in non-blocking mode
413 * @exception SocketTimeoutException If the timeout is reached
415 * @since 1.4
417 public void connect(SocketAddress endpoint, int timeout)
418 throws IOException
420 if (isClosed())
421 throw new SocketException("socket is closed");
423 if (! (endpoint instanceof InetSocketAddress))
424 throw new IllegalArgumentException("unsupported address type");
426 // The Sun spec says that if we have an associated channel and
427 // it is in non-blocking mode, we throw an IllegalBlockingModeException.
428 // However, in our implementation if the channel itself initiated this
429 // operation, then we must honor it regardless of its blocking mode.
430 if (getChannel() != null && ! getChannel().isBlocking()
431 && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
432 throw new IllegalBlockingModeException();
434 if (! isBound())
435 bind(null);
439 getImpl().connect(endpoint, timeout);
441 catch (IOException exception)
443 close();
444 throw exception;
446 catch (RuntimeException exception)
448 close();
449 throw exception;
451 catch (Error error)
453 close();
454 throw error;
459 * Returns the address of the remote end of the socket. If this socket
460 * is not connected, then <code>null</code> is returned.
462 * @return The remote address this socket is connected to
464 public InetAddress getInetAddress()
466 if (! isConnected())
467 return null;
471 return getImpl().getInetAddress();
473 catch (SocketException e)
475 // This cannot happen as we are connected.
478 return null;
482 * Returns the local address to which this socket is bound. If this socket
483 * is not connected, then a wildcard address, for which
484 * @see isAnyLocalAddress() is <code>true</code>, is returned.
486 * @return The local address
488 * @since 1.1
490 public InetAddress getLocalAddress()
492 if (! isBound())
493 return InetAddress.ANY_IF;
495 InetAddress addr = null;
499 addr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
501 catch (SocketException e)
503 // (hopefully) shouldn't happen
504 // throw new java.lang.InternalError
505 // ("Error in PlainSocketImpl.getOption");
506 return null;
509 // FIXME: According to libgcj, checkConnect() is supposed to be called
510 // before performing this operation. Problems: 1) We don't have the
511 // addr until after we do it, so we do a post check. 2). The docs I
512 // see don't require this in the Socket case, only DatagramSocket, but
513 // we'll assume they mean both.
514 SecurityManager sm = System.getSecurityManager();
515 if (sm != null)
516 sm.checkConnect(addr.getHostName(), getLocalPort());
518 return addr;
522 * Returns the port number of the remote end of the socket connection. If
523 * this socket is not connected, then 0 is returned.
525 * @return The remote port this socket is connected to
527 public int getPort()
529 if (! isConnected())
530 return 0;
534 return getImpl().getPort();
536 catch (SocketException e)
538 // This cannot happen as we are connected.
541 return 0;
545 * Returns the local port number to which this socket is bound. If this
546 * socket is not connected, then -1 is returned.
548 * @return The local port
550 public int getLocalPort()
552 if (! isBound())
553 return -1;
557 if (getImpl() != null)
558 return getImpl().getLocalPort();
560 catch (SocketException e)
562 // This cannot happen as we are bound.
565 return -1;
569 * Returns local socket address.
571 * @return the local socket address, null if not bound
573 * @since 1.4
575 public SocketAddress getLocalSocketAddress()
577 if (! isBound())
578 return null;
580 InetAddress addr = getLocalAddress();
584 return new InetSocketAddress(addr, getImpl().getLocalPort());
586 catch (SocketException e)
588 // This cannot happen as we are bound.
589 return null;
594 * Returns the remote socket address.
596 * @return the remote socket address, null of not connected
598 * @since 1.4
600 public SocketAddress getRemoteSocketAddress()
602 if (! isConnected())
603 return null;
607 return new InetSocketAddress(getImpl().getInetAddress(),
608 getImpl().getPort());
610 catch (SocketException e)
612 // This cannot happen as we are connected.
613 return null;
618 * Returns an InputStream for reading from this socket.
620 * @return The InputStream object
622 * @exception IOException If an error occurs or Socket is not connected
624 public InputStream getInputStream() throws IOException
626 if (isClosed())
627 throw new SocketException("socket is closed");
629 if (! isConnected())
630 throw new IOException("not connected");
632 return getImpl().getInputStream();
636 * Returns an OutputStream for writing to this socket.
638 * @return The OutputStream object
640 * @exception IOException If an error occurs or Socket is not connected
642 public OutputStream getOutputStream() throws IOException
644 if (isClosed())
645 throw new SocketException("socket is closed");
647 if (! isConnected())
648 throw new IOException("not connected");
650 return getImpl().getOutputStream();
654 * Sets the TCP_NODELAY option on the socket.
656 * @param on true to enable, false to disable
658 * @exception SocketException If an error occurs or Socket is not connected
660 * @since 1.1
662 public void setTcpNoDelay(boolean on) throws SocketException
664 if (isClosed())
665 throw new SocketException("socket is closed");
667 getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
671 * Tests whether or not the TCP_NODELAY option is set on the socket.
672 * Returns true if enabled, false if disabled. When on it disables the
673 * Nagle algorithm which means that packets are always send immediatly and
674 * never merged together to reduce network trafic.
676 * @return Whether or not TCP_NODELAY is set
678 * @exception SocketException If an error occurs or Socket not connected
680 * @since 1.1
682 public boolean getTcpNoDelay() throws SocketException
684 if (isClosed())
685 throw new SocketException("socket is closed");
687 Object on = getImpl().getOption(SocketOptions.TCP_NODELAY);
689 if (on instanceof Boolean)
690 return (((Boolean) on).booleanValue());
691 else
692 throw new SocketException("Internal Error");
696 * Sets the value of the SO_LINGER option on the socket. If the
697 * SO_LINGER option is set on a socket and there is still data waiting to
698 * be sent when the socket is closed, then the close operation will block
699 * until either that data is delivered or until the timeout period
700 * expires. The linger interval is specified in hundreths of a second
701 * (platform specific?)
703 * @param on true to enable SO_LINGER, false to disable
704 * @param linger The SO_LINGER timeout in hundreths of a second or -1 if
705 * SO_LINGER not set.
707 * @exception SocketException If an error occurs or Socket not connected
708 * @exception IllegalArgumentException If linger is negative
710 * @since 1.1
712 public void setSoLinger(boolean on, int linger) throws SocketException
714 if (isClosed())
715 throw new SocketException("socket is closed");
717 if (on)
719 if (linger < 0)
720 throw new IllegalArgumentException("SO_LINGER must be >= 0");
722 if (linger > 65535)
723 linger = 65535;
725 getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
727 else
728 getImpl().setOption(SocketOptions.SO_LINGER, Boolean.valueOf(false));
732 * Returns the value of the SO_LINGER option on the socket. If the
733 * SO_LINGER option is set on a socket and there is still data waiting to
734 * be sent when the socket is closed, then the close operation will block
735 * until either that data is delivered or until the timeout period
736 * expires. This method either returns the timeouts (in hundredths of
737 * of a second (platform specific?)) if SO_LINGER is set, or -1 if
738 * SO_LINGER is not set.
740 * @return The SO_LINGER timeout in hundreths of a second or -1
741 * if SO_LINGER not set
743 * @exception SocketException If an error occurs or Socket is not connected
745 * @since 1.1
747 public int getSoLinger() throws SocketException
749 if (isClosed())
750 throw new SocketException("socket is closed");
752 Object linger = getImpl().getOption(SocketOptions.SO_LINGER);
754 if (linger instanceof Integer)
755 return (((Integer) linger).intValue());
756 else
757 return -1;
761 * Sends urgent data through the socket
763 * @param data The data to send.
764 * Only the lowest eight bits of data are sent
766 * @exception IOException If an error occurs
768 * @since 1.4
770 public void sendUrgentData(int data) throws IOException
772 if (isClosed())
773 throw new SocketException("socket is closed");
775 getImpl().sendUrgentData(data);
779 * Enables/disables the SO_OOBINLINE option
781 * @param on True if SO_OOBLINE should be enabled
783 * @exception SocketException If an error occurs
785 * @since 1.4
787 public void setOOBInline(boolean on) throws SocketException
789 if (isClosed())
790 throw new SocketException("socket is closed");
792 getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
796 * Returns the current setting of the SO_OOBINLINE option for this socket
798 * @return True if SO_OOBINLINE is set, false otherwise.
800 * @exception SocketException If an error occurs
802 * @since 1.4
804 public boolean getOOBInline() throws SocketException
806 if (isClosed())
807 throw new SocketException("socket is closed");
809 Object buf = getImpl().getOption(SocketOptions.SO_OOBINLINE);
811 if (buf instanceof Boolean)
812 return (((Boolean) buf).booleanValue());
813 else
814 throw new SocketException("Internal Error: Unexpected type");
818 * Sets the value of the SO_TIMEOUT option on the socket. If this value
819 * is set, and an read/write is performed that does not complete within
820 * the timeout period, a short count is returned (or an EWOULDBLOCK signal
821 * would be sent in Unix if no data had been read). A value of 0 for
822 * this option implies that there is no timeout (ie, operations will
823 * block forever). On systems that have separate read and write timeout
824 * values, this method returns the read timeout. This
825 * value is in milliseconds.
827 * @param timeout The length of the timeout in milliseconds, or
828 * 0 to indicate no timeout.
830 * @exception SocketException If an error occurs or Socket not connected
832 * @since 1.1
834 public synchronized void setSoTimeout(int timeout) throws SocketException
836 if (isClosed())
837 throw new SocketException("socket is closed");
839 if (timeout < 0)
840 throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
842 getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
846 * Returns the value of the SO_TIMEOUT option on the socket. If this value
847 * is set, and an read/write is performed that does not complete within
848 * the timeout period, a short count is returned (or an EWOULDBLOCK signal
849 * would be sent in Unix if no data had been read). A value of 0 for
850 * this option implies that there is no timeout (ie, operations will
851 * block forever). On systems that have separate read and write timeout
852 * values, this method returns the read timeout. This
853 * value is in thousandths of a second (implementation specific?).
855 * @return The length of the timeout in thousandth's of a second or 0
856 * if not set
858 * @exception SocketException If an error occurs or Socket not connected
860 * @since 1.1
862 public synchronized int getSoTimeout() throws SocketException
864 if (isClosed())
865 throw new SocketException("socket is closed");
867 Object timeout = getImpl().getOption(SocketOptions.SO_TIMEOUT);
868 if (timeout instanceof Integer)
869 return (((Integer) timeout).intValue());
870 else
871 return 0;
875 * This method sets the value for the system level socket option
876 * SO_SNDBUF to the specified value. Note that valid values for this
877 * option are specific to a given operating system.
879 * @param size The new send buffer size.
881 * @exception SocketException If an error occurs or Socket not connected
882 * @exception IllegalArgumentException If size is 0 or negative
884 * @since 1.2
886 public void setSendBufferSize(int size) throws SocketException
888 if (isClosed())
889 throw new SocketException("socket is closed");
891 if (size <= 0)
892 throw new IllegalArgumentException("SO_SNDBUF value must be > 0");
894 getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
898 * This method returns the value of the system level socket option
899 * SO_SNDBUF, which is used by the operating system to tune buffer
900 * sizes for data transfers.
902 * @return The send buffer size.
904 * @exception SocketException If an error occurs or socket not connected
906 * @since 1.2
908 public int getSendBufferSize() throws SocketException
910 if (isClosed())
911 throw new SocketException("socket is closed");
913 Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF);
915 if (buf instanceof Integer)
916 return (((Integer) buf).intValue());
917 else
918 throw new SocketException("Internal Error: Unexpected type");
922 * This method sets the value for the system level socket option
923 * SO_RCVBUF to the specified value. Note that valid values for this
924 * option are specific to a given operating system.
926 * @param size The new receive buffer size.
928 * @exception SocketException If an error occurs or Socket is not connected
929 * @exception IllegalArgumentException If size is 0 or negative
931 * @since 1.2
933 public void setReceiveBufferSize(int size) throws SocketException
935 if (isClosed())
936 throw new SocketException("socket is closed");
938 if (size <= 0)
939 throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
941 getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
945 * This method returns the value of the system level socket option
946 * SO_RCVBUF, which is used by the operating system to tune buffer
947 * sizes for data transfers.
949 * @return The receive buffer size.
951 * @exception SocketException If an error occurs or Socket is not connected
953 * @since 1.2
955 public int getReceiveBufferSize() throws SocketException
957 if (isClosed())
958 throw new SocketException("socket is closed");
960 Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF);
962 if (buf instanceof Integer)
963 return (((Integer) buf).intValue());
964 else
965 throw new SocketException("Internal Error: Unexpected type");
969 * This method sets the value for the socket level socket option
970 * SO_KEEPALIVE.
972 * @param on True if SO_KEEPALIVE should be enabled
974 * @exception SocketException If an error occurs or Socket is not connected
976 * @since 1.3
978 public void setKeepAlive(boolean on) throws SocketException
980 if (isClosed())
981 throw new SocketException("socket is closed");
983 getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
987 * This method returns the value of the socket level socket option
988 * SO_KEEPALIVE.
990 * @return The setting
992 * @exception SocketException If an error occurs or Socket is not connected
994 * @since 1.3
996 public boolean getKeepAlive() throws SocketException
998 if (isClosed())
999 throw new SocketException("socket is closed");
1001 Object buf = getImpl().getOption(SocketOptions.SO_KEEPALIVE);
1003 if (buf instanceof Boolean)
1004 return (((Boolean) buf).booleanValue());
1005 else
1006 throw new SocketException("Internal Error: Unexpected type");
1010 * Closes the socket.
1012 * @exception IOException If an error occurs
1014 public synchronized void close() throws IOException
1016 if (isClosed())
1017 return;
1019 getImpl().close();
1020 impl = null;
1021 bound = false;
1023 if (getChannel() != null)
1024 getChannel().close();
1028 * Converts this <code>Socket</code> to a <code>String</code>.
1030 * @return The <code>String</code> representation of this <code>Socket</code>
1032 public String toString()
1036 if (isConnected())
1037 return ("Socket[addr=" + getImpl().getInetAddress() + ",port="
1038 + getImpl().getPort() + ",localport="
1039 + getImpl().getLocalPort() + "]");
1041 catch (SocketException e)
1043 // This cannot happen as we are connected.
1046 return "Socket[unconnected]";
1050 * Sets the <code>SocketImplFactory</code>. This may be done only once per
1051 * virtual machine. Subsequent attempts will generate a
1052 * <code>SocketException</code>. Note that a <code>SecurityManager</code>
1053 * check is made prior to setting the factory. If
1054 * insufficient privileges exist to set the factory, then an
1055 * <code>IOException</code> will be thrown.
1057 * @param fac the factory to set
1059 * @exception SecurityException If the <code>SecurityManager</code> does
1060 * not allow this operation.
1061 * @exception SocketException If the SocketImplFactory is already defined
1062 * @exception IOException If any other error occurs
1064 public static synchronized void setSocketImplFactory(SocketImplFactory fac)
1065 throws IOException
1067 // See if already set
1068 if (factory != null)
1069 throw new SocketException("SocketImplFactory already defined");
1071 // Check permissions
1072 SecurityManager sm = System.getSecurityManager();
1073 if (sm != null)
1074 sm.checkSetFactory();
1076 if (fac == null)
1077 throw new SocketException("SocketImplFactory cannot be null");
1079 factory = fac;
1083 * Closes the input side of the socket stream.
1085 * @exception IOException If an error occurs.
1087 * @since 1.3
1089 public void shutdownInput() throws IOException
1091 if (isClosed())
1092 throw new SocketException("socket is closed");
1094 getImpl().shutdownInput();
1095 inputShutdown = true;
1099 * Closes the output side of the socket stream.
1101 * @exception IOException If an error occurs.
1103 * @since 1.3
1105 public void shutdownOutput() throws IOException
1107 if (isClosed())
1108 throw new SocketException("socket is closed");
1110 getImpl().shutdownOutput();
1111 outputShutdown = true;
1115 * Returns the socket channel associated with this socket.
1117 * @return the associated socket channel,
1118 * null if no associated channel exists
1120 * @since 1.4
1122 public SocketChannel getChannel()
1124 return null;
1128 * Checks if the SO_REUSEADDR option is enabled
1130 * @return True if SO_REUSEADDR is set, false otherwise.
1132 * @exception SocketException If an error occurs
1134 * @since 1.4
1136 public boolean getReuseAddress() throws SocketException
1138 if (isClosed())
1139 throw new SocketException("socket is closed");
1141 Object reuseaddr = getImpl().getOption(SocketOptions.SO_REUSEADDR);
1143 if (! (reuseaddr instanceof Boolean))
1144 throw new SocketException("Internal Error");
1146 return ((Boolean) reuseaddr).booleanValue();
1150 * Enables/Disables the SO_REUSEADDR option
1152 * @param reuseAddress true if SO_REUSEADDR should be enabled,
1153 * false otherwise
1155 * @exception SocketException If an error occurs
1157 * @since 1.4
1159 public void setReuseAddress(boolean reuseAddress) throws SocketException
1161 if (isClosed())
1162 throw new SocketException("socket is closed");
1164 getImpl().setOption(SocketOptions.SO_REUSEADDR,
1165 Boolean.valueOf(reuseAddress));
1169 * Returns the current traffic class
1171 * @return The current traffic class.
1173 * @exception SocketException If an error occurs
1175 * @see Socket#setTrafficClass(int tc)
1177 * @since 1.4
1179 public int getTrafficClass() throws SocketException
1181 if (isClosed())
1182 throw new SocketException("socket is closed");
1184 Object obj = getImpl().getOption(SocketOptions.IP_TOS);
1186 if (obj instanceof Integer)
1187 return ((Integer) obj).intValue();
1188 else
1189 throw new SocketException("Unexpected type");
1193 * Sets the traffic class value
1195 * @param tc The traffic class
1197 * @exception SocketException If an error occurs
1198 * @exception IllegalArgumentException If tc value is illegal
1200 * @see Socket#getTrafficClass()
1202 * @since 1.4
1204 public void setTrafficClass(int tc) throws SocketException
1206 if (isClosed())
1207 throw new SocketException("socket is closed");
1209 if (tc < 0 || tc > 255)
1210 throw new IllegalArgumentException();
1212 getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
1216 * Checks if the socket is connected
1218 * @return True if socket is connected, false otherwise.
1220 * @since 1.4
1222 public boolean isConnected()
1226 if (getImpl() == null)
1227 return false;
1229 return getImpl().getInetAddress() != null;
1231 catch (SocketException e)
1233 return false;
1238 * Checks if the socket is already bound.
1240 * @return True if socket is bound, false otherwise.
1242 * @since 1.4
1244 public boolean isBound()
1246 return bound;
1250 * Checks if the socket is closed.
1252 * @return True if socket is closed, false otherwise.
1254 * @since 1.4
1256 public boolean isClosed()
1258 return impl == null;
1262 * Checks if the socket's input stream is shutdown
1264 * @return True if input is shut down.
1266 * @since 1.4
1268 public boolean isInputShutdown()
1270 return inputShutdown;
1274 * Checks if the socket's output stream is shutdown
1276 * @return True if output is shut down.
1278 * @since 1.4
1280 public boolean isOutputShutdown()
1282 return outputShutdown;