InetAddress.java (ANY_IF): moved from ServerSocket.
[gcc.git] / libjava / java / net / Socket.java
1 /* Socket.java -- Client socket implementation
2 Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 As a special exception, if you link this library with other files to
22 produce an executable, this library does not by itself cause the
23 resulting executable to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why the
25 executable file might be covered by the GNU General Public License. */
26
27 package java.net;
28
29 import java.io.*;
30
31 /* Written using on-line Java Platform 1.2 API Specification.
32 * Status: I believe all methods are implemented.
33 */
34
35 /**
36 * This class models a client site socket. A socket is a TCP/IP endpoint
37 * for network communications conceptually similar to a file handle.
38 * <p>
39 * This class does not actually do any work. Instead, it redirects all of
40 * its calls to a socket implementation object which implements the
41 * <code>SocketImpl</code> interface. The implementation class is
42 * instantiated by factory class that implements the
43 * <code>SocketImplFactory interface</code>. A default
44 * factory is provided, however the factory may be set by a call to
45 * the <code>setSocketImplFactory</code> method. Note that this may only be
46 * done once per virtual machine. If a subsequent attempt is made to set the
47 * factory, a <code>SocketException</code> will be thrown.
48 *
49 * @author Aaron M. Renn (arenn@urbanophile.com)
50 * @author Per Bothner (bothner@cygnus.com)
51 */
52 public class Socket
53 {
54
55 // Class Variables
56
57 /**
58 * This is the user SocketImplFactory for this class. If this variable is
59 * null, a default factory is used.
60 */
61 static SocketImplFactory factory;
62
63 // Instance Variables
64
65 /**
66 * The implementation object to which calls are redirected
67 */
68 SocketImpl impl;
69
70 // Constructors
71
72 /**
73 * Initializes a new instance of <code>Socket</code> object without
74 * connecting to a remote host. This useful for subclasses of socket that
75 * might want this behavior.
76 */
77 protected Socket ()
78 {
79 if (factory != null)
80 impl = factory.createSocketImpl();
81 else
82 impl = new PlainSocketImpl();
83 }
84
85 /**
86 * Initializes a new instance of <code>Socket</code> object without
87 * connecting to a remote host. This is useful for subclasses of socket
88 * that might want this behavior.
89 * <p>
90 * Additionally, this socket will be created using the supplied
91 * implementation class instead the default class or one returned by a
92 * factory. This value can be <code>null</code>, but if it is, all instance
93 * methods in <code>Socket</code> should be overridden because most of them
94 * rely on this value being populated.
95 *
96 * @param impl The <code>SocketImpl</code> to use for this
97 * <code>Socket</code>
98 *
99 * @exception SocketException If an error occurs
100 */
101 protected Socket (SocketImpl impl) throws SocketException
102 {
103 this.impl = impl;
104 }
105
106 /**
107 * Initializes a new instance of <code>Socket</code> and connects to the
108 * hostname and port specified as arguments.
109 *
110 * @param host The name of the host to connect to
111 * @param port The port number to connect to
112 *
113 * @exception UnknownHostException If the hostname cannot be resolved to a
114 * network address.
115 * @exception IOException If an error occurs
116 */
117 public Socket (String host, int port)
118 throws UnknownHostException, IOException
119 {
120 this(InetAddress.getByName(host), port, null, 0, true);
121 }
122
123 /**
124 * Initializes a new instance of <code>Socket</code> and connects to the
125 * address and port number specified as arguments.
126 *
127 * @param address The address to connect to
128 * @param port The port number to connect to
129 *
130 * @exception IOException If an error occurs
131 */
132 public Socket (InetAddress address, int port)
133 throws IOException
134 {
135 this(address, port, null, 0, true);
136 }
137
138 /**
139 * Initializes a new instance of <code>Socket</code> that connects to the
140 * named host on the specified port and binds to the specified local address
141 * and port.
142 *
143 * @param host The name of the remote host to connect to.
144 * @param port The remote port to connect to.
145 * @param loadAddr The local address to bind to.
146 * @param localPort The local port to bind to.
147 *
148 * @exception SecurityException If the <code>SecurityManager</code>
149 * exists and does not allow a connection to the specified host/port or
150 * binding to the specified local host/port.
151 * @exception IOException If a connection error occurs.
152 */
153 public Socket (String host, int port,
154 InetAddress localAddr, int localPort) throws IOException
155 {
156 this(InetAddress.getByName(host), port, localAddr, localPort, true);
157 }
158
159 /**
160 * Initializes a new instance of <code>Socket</code> and connects to the
161 * address and port number specified as arguments, plus binds to the
162 * specified local address and port.
163 *
164 * @param address The remote address to connect to
165 * @param port The remote port to connect to
166 * @param localAddr The local address to connect to
167 * @param localPort The local port to connect to
168 *
169 * @exception IOException If an error occurs
170 */
171 public Socket (InetAddress address, int port,
172 InetAddress localAddr, int localPort) throws IOException
173 {
174 this(address, port, localAddr, localPort, true);
175 }
176
177 /**
178 * Initializes a new instance of <code>Socket</code> and connects to the
179 * hostname and port specified as arguments. If the stream argument is set
180 * to <code>true</code>, then a stream socket is created. If it is
181 * <code>false</code>, a datagram socket is created.
182 *
183 * @param host The name of the host to connect to
184 * @param port The port to connect to
185 * @param stream <code>true</code> for a stream socket, <code>false</code>
186 * for a datagram socket
187 *
188 * @exception IOException If an error occurs
189 *
190 * @deprecated Use the <code>DatagramSocket</code> class to create
191 * datagram oriented sockets.
192 */
193 public Socket (String host, int port, boolean stream) throws IOException
194 {
195 this(InetAddress.getByName(host), port, null, 0, stream);
196 }
197
198 /**
199 * Initializes a new instance of <code>Socket</code> and connects to the
200 * address and port number specified as arguments. If the stream param is
201 * <code>true</code>, a stream socket will be created, otherwise a datagram
202 * socket is created.
203 *
204 * @param host The address to connect to
205 * @param port The port number to connect to
206 * @param stream <code>true</code> to create a stream socket,
207 * <code>false</code> to create a datagram socket.
208 *
209 * @exception IOException If an error occurs
210 *
211 * @deprecated Use the <code>DatagramSocket</code> class to create
212 * datagram oriented sockets.
213 */
214 public Socket (InetAddress host, int port, boolean stream) throws IOException
215 {
216 this(host, port, null, 0, stream);
217 }
218
219 /**
220 * This constructor is where the real work takes place. Connect to the
221 * specified address and port. Use default local values if not specified,
222 * otherwise use the local host and port passed in. Create as stream or
223 * datagram based on "stream" argument.
224 * <p>
225 *
226 * @param raddr The remote address to connect to
227 * @param rport The remote port to connect to
228 * @param laddr The local address to connect to
229 * @param lport The local port to connect to
230 * @param stream true for a stream socket, false for a datagram socket
231 *
232 * @exception IOException If an error occurs
233 */
234 private Socket(InetAddress raddr, int rport, InetAddress laddr, int lport,
235 boolean stream) throws IOException
236 {
237 this();
238 if (impl == null)
239 throw new IOException("Cannot initialize Socket implementation");
240
241 SecurityManager sm = System.getSecurityManager();
242 if (sm != null)
243 sm.checkConnect(raddr.getHostName(), rport);
244
245 impl.create(stream);
246
247 // FIXME: JCL p. 1586 says if localPort is unspecified, bind to any port,
248 // i.e. '0' and if localAddr is unspecified, use getLocalAddress() as
249 // that default. JDK 1.2 doc infers not to do a bind.
250 if (laddr != null)
251 impl.bind(laddr, lport);
252
253 if (raddr != null)
254 impl.connect(raddr, rport);
255 }
256
257 /**
258 * Returns the address of the remote end of the socket. If this socket
259 * is not connected, then <code>null</code> is returned.
260 *
261 * @return The remote address this socket is connected to
262 */
263 public InetAddress getInetAddress ()
264 {
265 if (impl != null)
266 return impl.getInetAddress();
267
268 return null;
269 }
270
271 /**
272 * Returns the local address to which this socket is bound. If this socket
273 * is not connected, then <code>null</code> is returned.
274 *
275 * @return The local address
276 */
277 public InetAddress getLocalAddress ()
278 {
279 if (impl == null)
280 return null;
281
282 InetAddress addr = null;
283 try
284 {
285 addr = (InetAddress)impl.getOption(SocketOptions.SO_BINDADDR);
286 }
287 catch(SocketException e)
288 {
289 // (hopefully) shouldn't happen
290 // throw new java.lang.InternalError
291 // ("Error in PlainSocketImpl.getOption");
292 return null;
293 }
294
295 // FIXME: According to libgcj, checkConnect() is supposed to be called
296 // before performing this operation. Problems: 1) We don't have the
297 // addr until after we do it, so we do a post check. 2). The docs I
298 // see don't require this in the Socket case, only DatagramSocket, but
299 // we'll assume they mean both.
300 SecurityManager sm = System.getSecurityManager();
301 if (sm != null)
302 sm.checkConnect(addr.getHostName(), getLocalPort());
303
304 return addr;
305 }
306
307 /**
308 * Returns the port number of the remote end of the socket connection. If
309 * this socket is not connected, then -1 is returned.
310 *
311 * @return The remote port this socket is connected to
312 */
313 public int getPort ()
314 {
315 if (impl != null)
316 return impl.getPort();
317
318 return -1;
319 }
320
321 /**
322 * Returns the local port number to which this socket is bound. If this
323 * socket is not connected, then -1 is returned.
324 *
325 * @return The local port
326 */
327 public int getLocalPort ()
328 {
329 if (impl != null)
330 return impl.getLocalPort();
331
332 return -1;
333 }
334
335 /**
336 * Returns an InputStream for reading from this socket.
337 *
338 * @return The InputStream object
339 *
340 * @exception IOException If an error occurs or Socket is not connected
341 */
342 public InputStream getInputStream () throws IOException
343 {
344 if (impl != null)
345 return(impl.getInputStream());
346
347 throw new IOException("Not connected");
348 }
349
350 /**
351 * Returns an OutputStream for writing to this socket.
352 *
353 * @return The OutputStream object
354 *
355 * @exception IOException If an error occurs or Socket is not connected
356 */
357 public OutputStream getOutputStream () throws IOException
358 {
359 if (impl != null)
360 return impl.getOutputStream();
361
362 throw new IOException("Not connected");
363 }
364
365 /**
366 * Sets the TCP_NODELAY option on the socket.
367 *
368 * @param on true to enable, false to disable
369 *
370 * @exception SocketException If an error occurs or Socket is not connected
371 */
372 public void setTcpNoDelay (boolean on) throws SocketException
373 {
374 if (impl == null)
375 throw new SocketException("Not connected");
376
377 impl.setOption(SocketOptions.TCP_NODELAY, new Boolean(on));
378 }
379
380 /**
381 * Tests whether or not the TCP_NODELAY option is set on the socket.
382 * Returns true if enabled, false if disabled. When on it disables the
383 * Nagle algorithm which means that packets are always send immediatly and
384 * never merged together to reduce network trafic.
385 *
386 * @return Whether or not TCP_NODELAY is set
387 *
388 * @exception SocketException If an error occurs or Socket not connected
389 */
390 public boolean getTcpNoDelay() throws SocketException
391 {
392 if (impl == null)
393 throw new SocketException("Not connected");
394
395 Object on = impl.getOption(SocketOptions.TCP_NODELAY);
396
397 if (on instanceof Boolean)
398 return(((Boolean)on).booleanValue());
399 else
400 throw new SocketException("Internal Error");
401 }
402
403 /**
404 * Sets the value of the SO_LINGER option on the socket. If the
405 * SO_LINGER option is set on a socket and there is still data waiting to
406 * be sent when the socket is closed, then the close operation will block
407 * until either that data is delivered or until the timeout period
408 * expires. The linger interval is specified in hundreths of a second
409 * (platform specific?)
410 *
411 * @param on true to enable SO_LINGER, false to disable
412 * @param linger The SO_LINGER timeout in hundreths of a second or -1 if
413 * SO_LINGER not set.
414 *
415 * @exception SocketException If an error occurs or Socket not connected
416 */
417 public void setSoLinger(boolean on, int linger) throws SocketException
418 {
419 if (impl == null)
420 throw new SocketException("No socket created");
421
422 if (on == true)
423 {
424 if (linger < 0)
425 throw new IllegalArgumentException("SO_LINGER must be >= 0");
426
427 if (linger > 65535)
428 linger = 65535;
429
430 impl.setOption(SocketOptions.SO_LINGER, new Integer(linger));
431 }
432 else
433 {
434 impl.setOption(SocketOptions.SO_LINGER, new Boolean(false));
435 }
436 }
437
438 /**
439 * Returns the value of the SO_LINGER option on the socket. If the
440 * SO_LINGER option is set on a socket and there is still data waiting to
441 * be sent when the socket is closed, then the close operation will block
442 * until either that data is delivered or until the timeout period
443 * expires. This method either returns the timeouts (in hundredths of
444 * of a second (platform specific?)) if SO_LINGER is set, or -1 if
445 * SO_LINGER is not set.
446 *
447 * @return The SO_LINGER timeout in hundreths of a second or -1
448 * if SO_LINGER not set
449 *
450 * @exception SocketException If an error occurs or Socket is not connected
451 */
452 public int getSoLinger() throws SocketException
453 {
454 if (impl == null)
455 throw new SocketException("Not connected");
456
457 Object linger = impl.getOption(SocketOptions.SO_LINGER);
458 if (linger instanceof Integer)
459 return(((Integer)linger).intValue());
460 else
461 return -1;
462 }
463
464 /**
465 * Sets the value of the SO_TIMEOUT option on the socket. If this value
466 * is set, and an read/write is performed that does not complete within
467 * the timeout period, a short count is returned (or an EWOULDBLOCK signal
468 * would be sent in Unix if no data had been read). A value of 0 for
469 * this option implies that there is no timeout (ie, operations will
470 * block forever). On systems that have separate read and write timeout
471 * values, this method returns the read timeout. This
472 * value is in thousandths of a second (****????*****)
473 *
474 * @param timeout The length of the timeout in thousandth's of a second or
475 * 0 if not set
476 *
477 * @exception SocketException If an error occurs or Socket not connected
478 */
479 public synchronized void setSoTimeout (int timeout) throws SocketException
480 {
481 if (impl == null)
482 throw new SocketException("Not connected");
483
484 if (timeout < 0)
485 throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
486
487 impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
488 }
489
490 /**
491 * Returns the value of the SO_TIMEOUT option on the socket. If this value
492 * is set, and an read/write is performed that does not complete within
493 * the timeout period, a short count is returned (or an EWOULDBLOCK signal
494 * would be sent in Unix if no data had been read). A value of 0 for
495 * this option implies that there is no timeout (ie, operations will
496 * block forever). On systems that have separate read and write timeout
497 * values, this method returns the read timeout. This
498 * value is in thousandths of a second (implementation specific?).
499 *
500 * @return The length of the timeout in thousandth's of a second or 0
501 * if not set
502 *
503 * @exception SocketException If an error occurs or Socket not connected
504 */
505 public synchronized int getSoTimeout () throws SocketException
506 {
507 if (impl == null)
508 throw new SocketException("Not connected");
509
510 Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);
511 if (timeout instanceof Integer)
512 return(((Integer)timeout).intValue());
513 else
514 return 0;
515 }
516
517 /**
518 * This method sets the value for the system level socket option
519 * SO_SNDBUF to the specified value. Note that valid values for this
520 * option are specific to a given operating system.
521 *
522 * @param size The new send buffer size.
523 *
524 * @exception SocketException If an error occurs or Socket not connected
525 *
526 * @since Java 1.2
527 */
528 public void setSendBufferSize (int size) throws SocketException
529 {
530 if (impl == null)
531 throw new SocketException("Not connected");
532
533 if (size <= 0)
534 throw new IllegalArgumentException("SO_SNDBUF value must be > 0");
535
536 impl.setOption(SocketOptions.SO_SNDBUF, new Integer(size));
537 }
538
539 /**
540 * This method returns the value of the system level socket option
541 * SO_SNDBUF, which is used by the operating system to tune buffer
542 * sizes for data transfers.
543 *
544 * @return The send buffer size.
545 *
546 * @exception SocketException If an error occurs or socket not connected
547 *
548 * @since Java 1.2
549 */
550 public int getSendBufferSize () throws SocketException
551 {
552 if (impl == null)
553 throw new SocketException("Not connected");
554
555 Object buf = impl.getOption(SocketOptions.SO_SNDBUF);
556
557 if (buf instanceof Integer)
558 return(((Integer)buf).intValue());
559 else
560 throw new SocketException("Internal Error: Unexpected type");
561 }
562
563 /**
564 * This method sets the value for the system level socket option
565 * SO_RCVBUF to the specified value. Note that valid values for this
566 * option are specific to a given operating system.
567 *
568 * @param size The new receive buffer size.
569 *
570 * @exception SocketException If an error occurs or Socket is not connected
571 *
572 * @since Java 1.2
573 */
574 public void setReceiveBufferSize (int size) throws SocketException
575 {
576 if (impl == null)
577 throw new SocketException("Not connected");
578
579 if (size <= 0)
580 throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
581
582 impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size));
583 }
584
585 /**
586 * This method returns the value of the system level socket option
587 * SO_RCVBUF, which is used by the operating system to tune buffer
588 * sizes for data transfers.
589 *
590 * @return The receive buffer size.
591 *
592 * @exception SocketException If an error occurs or Socket is not connected
593 *
594 * @since Java 1.2
595 */
596 public int getReceiveBufferSize () throws SocketException
597 {
598 if (impl == null)
599 throw new SocketException("Not connected");
600
601 Object buf = impl.getOption(SocketOptions.SO_RCVBUF);
602
603 if (buf instanceof Integer)
604 return(((Integer)buf).intValue());
605 else
606 throw new SocketException("Internal Error: Unexpected type");
607 }
608
609 /**
610 * Closes the socket.
611 *
612 * @exception IOException If an error occurs
613 */
614 public synchronized void close () throws IOException
615 {
616 if (impl != null)
617 impl.close();
618 }
619
620 /**
621 * Converts this <code>Socket</code> to a <code>String</code>.
622 *
623 * @return The <code>String</code> representation of this <code>Socket</code>
624 */
625 public String toString ()
626 {
627 return("Socket " + impl);
628 }
629
630 // Class Methods
631
632 /**
633 * Sets the <code>SocketImplFactory</code>. This may be done only once per
634 * virtual machine. Subsequent attempts will generate a
635 * <code>SocketException</code>. Note that a <code>SecurityManager</code>
636 * check is made prior to setting the factory. If
637 * insufficient privileges exist to set the factory, then an
638 * <code>IOException</code> will be thrown.
639 *
640 * @exception SecurityException If the <code>SecurityManager</code> does
641 * not allow this operation.
642 * @exception SocketException If the SocketImplFactory is already defined
643 * @exception IOException If any other error occurs
644 */
645 public static synchronized void setSocketImplFactory (SocketImplFactory fac)
646 throws IOException
647 {
648 // See if already set
649 if (factory != null)
650 throw new SocketException("SocketImplFactory already defined");
651
652 // Check permissions
653 SecurityManager sm = System.getSecurityManager();
654 if (sm != null)
655 sm.checkSetFactory();
656
657 factory = fac;
658 }
659 }