OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [net/] [Socket.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* Socket.java -- Client socket implementation
2
   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2006, 2007
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
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.
11
 
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.
16
 
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., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
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.
26
 
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. */
38
 
39
package java.net;
40
 
41
import gnu.java.net.PlainSocketImpl;
42
 
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;
48
 
49
 
50
/* Written using on-line Java Platform 1.2 API Specification.
51
 * Status:  I believe all methods are implemented.
52
 */
53
 
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.
67
 *
68
 * @author Aaron M. Renn (arenn@urbanophile.com)
69
 * @author Per Bothner (bothner@cygnus.com)
70
 */
71
public class Socket
72
{
73
  /**
74
   * This is the user SocketImplFactory for this class.  If this variable is
75
   * null, a default factory is used.
76
   */
77
  static SocketImplFactory factory;
78
 
79
  /**
80
   * The implementation object to which calls are redirected
81
   */
82
  // package-private because ServerSocket.implAccept() needs to access it.
83
  SocketImpl impl;
84
 
85
  /**
86
   * True if impl.create() has been called.
87
   */
88
  // package-private because ServerSocket.implAccept() needs to access it.
89
  boolean implCreated;
90
 
91
  /**
92
   * True if the socket is bound.
93
   * Package private so it can be set from ServerSocket when accept is called.
94
   */
95
  boolean bound;
96
 
97
  /**
98
   * True if input is shutdown.
99
   */
100
  private boolean inputShutdown;
101
 
102
  /**
103
   * True if output is shutdown.
104
   */
105
  private boolean outputShutdown;
106
 
107
  /**
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.
111
   *
112
   * @specnote This constructor is public since JDK 1.4
113
   * @since 1.1
114
   */
115
  public Socket()
116
  {
117
    if (factory != null)
118
      impl = factory.createSocketImpl();
119
    else
120
      impl = new PlainSocketImpl();
121
  }
122
 
123
  /**
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.
132
   *
133
   * @param impl The <code>SocketImpl</code> to use for this
134
   *             <code>Socket</code>
135
   *
136
   * @exception SocketException If an error occurs
137
   *
138
   * @since 1.1
139
   */
140
  protected Socket(SocketImpl impl) throws SocketException
141
  {
142
    if (impl == null)
143
      this.impl = new PlainSocketImpl();
144
    else
145
      this.impl = impl;
146
  }
147
 
148
  /**
149
   * Initializes a new instance of <code>Socket</code> and connects to the
150
   * hostname and port specified as arguments.
151
   *
152
   * @param host The name of the host to connect to
153
   * @param port The port number to connect to
154
   *
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
160
   */
161
  public Socket(String host, int port)
162
    throws UnknownHostException, IOException
163
  {
164
    this(InetAddress.getByName(host), port, null, 0, true);
165
  }
166
 
167
  /**
168
   * Initializes a new instance of <code>Socket</code> and connects to the
169
   * address and port number specified as arguments.
170
   *
171
   * @param address The address to connect to
172
   * @param port The port number to connect to
173
   *
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
177
   */
178
  public Socket(InetAddress address, int port) throws IOException
179
  {
180
    this(address, port, null, 0, true);
181
  }
182
 
183
  /**
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.
187
   *
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.
192
   *
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.
197
   *
198
   * @since 1.1
199
   */
200
  public Socket(String host, int port, InetAddress localAddr, int localPort)
201
    throws IOException
202
  {
203
    this(InetAddress.getByName(host), port, localAddr, localPort, true);
204
  }
205
 
206
  /**
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.
210
   *
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
215
   *
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
219
   *
220
   * @since 1.1
221
   */
222
  public Socket(InetAddress address, int port, InetAddress localAddr,
223
                int localPort) throws IOException
224
  {
225
    this(address, port, localAddr, localPort, true);
226
  }
227
 
228
  /**
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.
233
   *
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
238
   *
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
242
   *
243
   * @deprecated Use the <code>DatagramSocket</code> class to create
244
   * datagram oriented sockets.
245
   */
246
  public Socket(String host, int port, boolean stream)
247
    throws IOException
248
  {
249
    this(InetAddress.getByName(host), port, null, 0, stream);
250
  }
251
 
252
  /**
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.
257
   *
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.
262
   *
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
266
   *
267
   * @deprecated Use the <code>DatagramSocket</code> class to create
268
   * datagram oriented sockets.
269
   */
270
  public Socket(InetAddress host, int port, boolean stream)
271
    throws IOException
272
  {
273
    this(host, port, null, 0, stream);
274
  }
275
 
276
  /**
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>
282
   *
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
288
   *
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
292
   */
293
  private Socket(InetAddress raddr, int rport, InetAddress laddr, int lport,
294
                 boolean stream) throws IOException
295
  {
296
    this();
297
 
298
    SecurityManager sm = System.getSecurityManager();
299
    if (sm != null)
300
      sm.checkConnect(raddr.getHostAddress(), rport);
301
 
302
    // bind socket
303
    SocketAddress bindaddr =
304
      laddr == null ? null : new InetSocketAddress(laddr, lport);
305
    bind(bindaddr);
306
 
307
    // Connect socket in case of Exceptions we must close the socket
308
    // because an exception in the constructor means that the caller will
309
    // not have a reference to this instance.
310
    // Note: You may have the idea that the exception treatment
311
    // should be moved into connect() but there is a Mauve test which
312
    // shows that a failed connect should not close the socket.
313
    try
314
      {
315
        connect(new InetSocketAddress(raddr, rport));
316
      }
317
    catch (IOException ioe)
318
      {
319
        impl.close();
320
        throw ioe;
321
      }
322
    catch (RuntimeException re)
323
      {
324
        impl.close();
325
        throw re;
326
      }
327
 
328
    // FIXME: JCL p. 1586 says if localPort is unspecified, bind to any port,
329
    // i.e. '0' and if localAddr is unspecified, use getLocalAddress() as
330
    // that default.  JDK 1.2 doc infers not to do a bind.
331
  }
332
 
333
  private SocketImpl getImpl() throws SocketException
334
  {
335
    if (! implCreated)
336
      {
337
        try
338
          {
339
            impl.create(true);
340
          }
341
        catch (IOException x)
342
          {
343
            throw (SocketException) new SocketException().initCause(x);
344
          }
345
        implCreated = true;
346
      }
347
    return impl;
348
  }
349
 
350
  /**
351
   * Binds the socket to the given local address/port
352
   *
353
   * @param bindpoint The address/port to bind to
354
   *
355
   * @exception IOException If an error occurs
356
   * @exception SecurityException If a security manager exists and its
357
   * checkConnect method doesn't allow the operation
358
   * @exception IllegalArgumentException If the address type is not supported
359
   *
360
   * @since 1.4
361
   */
362
  public void bind(SocketAddress bindpoint) throws IOException
363
  {
364
    if (isClosed())
365
      throw new SocketException("socket is closed");
366
 
367
    // XXX: JDK 1.4.1 API documentation says that if bindpoint is null the
368
    // socket will be bound to an ephemeral port and a valid local address.
369
    if (bindpoint == null)
370
      bindpoint = new InetSocketAddress(InetAddress.ANY_IF, 0);
371
 
372
    if (! (bindpoint instanceof InetSocketAddress))
373
      throw new IllegalArgumentException();
374
 
375
    InetSocketAddress tmp = (InetSocketAddress) bindpoint;
376
 
377
    // bind to address/port
378
    try
379
      {
380
        getImpl().bind(tmp.getAddress(), tmp.getPort());
381
        bound = true;
382
      }
383
    catch (IOException exception)
384
      {
385
        close();
386
        throw exception;
387
      }
388
    catch (RuntimeException exception)
389
      {
390
        close();
391
        throw exception;
392
      }
393
    catch (Error error)
394
      {
395
        close();
396
        throw error;
397
      }
398
  }
399
 
400
  /**
401
   * Connects the socket with a remote address.
402
   *
403
   * @param endpoint The address to connect to
404
   *
405
   * @exception IOException If an error occurs
406
   * @exception IllegalArgumentException If the addess type is not supported
407
   * @exception IllegalBlockingModeException If this socket has an associated
408
   * channel, and the channel is in non-blocking mode
409
   *
410
   * @since 1.4
411
   */
412
  public void connect(SocketAddress endpoint) throws IOException
413
  {
414
    connect(endpoint, 0);
415
  }
416
 
417
  /**
418
   * Connects the socket with a remote address. A timeout of zero is
419
   * interpreted as an infinite timeout. The connection will then block
420
   * until established or an error occurs.
421
   *
422
   * @param endpoint The address to connect to
423
   * @param timeout The length of the timeout in milliseconds, or
424
   * 0 to indicate no timeout.
425
   *
426
   * @exception IOException If an error occurs
427
   * @exception IllegalArgumentException If the address type is not supported
428
   * @exception IllegalBlockingModeException If this socket has an associated
429
   * channel, and the channel is in non-blocking mode
430
   * @exception SocketTimeoutException If the timeout is reached
431
   *
432
   * @since 1.4
433
   */
434
  public void connect(SocketAddress endpoint, int timeout)
435
    throws IOException
436
  {
437
    if (isClosed())
438
      throw new SocketException("socket is closed");
439
 
440
    if (! (endpoint instanceof InetSocketAddress))
441
      throw new IllegalArgumentException("unsupported address type");
442
 
443
    // The Sun spec says that if we have an associated channel and
444
    // it is in non-blocking mode, we throw an IllegalBlockingModeException.
445
    // However, in our implementation if the channel itself initiated this
446
    // operation, then we must honor it regardless of its blocking mode.
447
    if (getChannel() != null && ! getChannel().isBlocking()
448
        && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
449
      throw new IllegalBlockingModeException();
450
 
451
    if (! isBound())
452
      bind(null);
453
 
454
    getImpl().connect(endpoint, timeout);
455
  }
456
 
457
  /**
458
   * Returns the address of the remote end of the socket.  If this socket
459
   * is not connected, then <code>null</code> is returned.
460
   *
461
   * @return The remote address this socket is connected to
462
   */
463
  public InetAddress getInetAddress()
464
  {
465
    if (! isConnected())
466
      return null;
467
 
468
    try
469
      {
470
        return getImpl().getInetAddress();
471
      }
472
    catch (SocketException e)
473
      {
474
        // This cannot happen as we are connected.
475
      }
476
 
477
    return null;
478
  }
479
 
480
  /**
481
   * Returns the local address to which this socket is bound.  If this socket
482
   * is not connected, then a wildcard address, for which
483
   * @see InetAddress#isAnyLocalAddress() is <code>true</code>, is returned.
484
   *
485
   * @return The local address
486
   *
487
   * @since 1.1
488
   */
489
  public InetAddress getLocalAddress()
490
  {
491
    if (! isBound())
492
      return InetAddress.ANY_IF;
493
 
494
    InetAddress addr = null;
495
 
496
    if (impl instanceof PlainSocketImpl)
497
      addr = ((PlainSocketImpl) impl).getLocalAddress().getAddress();
498
 
499
    if (addr == null)
500
      {
501
        try
502
          {
503
            addr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
504
          }
505
        catch (SocketException e)
506
          {
507
            // (hopefully) shouldn't happen
508
            // throw new java.lang.InternalError
509
            //      ("Error in PlainSocketImpl.getOption");
510
            return null;
511
          }
512
      }
513
 
514
    // FIXME: According to libgcj, checkConnect() is supposed to be called
515
    // before performing this operation.  Problems: 1) We don't have the
516
    // addr until after we do it, so we do a post check.  2). The docs I
517
    // see don't require this in the Socket case, only DatagramSocket, but
518
    // we'll assume they mean both.
519
    SecurityManager sm = System.getSecurityManager();
520
    if (sm != null)
521
      sm.checkConnect(addr.getHostName(), getLocalPort());
522
 
523
    return addr;
524
  }
525
 
526
  /**
527
   * Returns the port number of the remote end of the socket connection.  If
528
   * this socket is not connected, then 0 is returned.
529
   *
530
   * @return The remote port this socket is connected to
531
   */
532
  public int getPort()
533
  {
534
    if (! isConnected())
535
      return 0;
536
 
537
    try
538
      {
539
        return getImpl().getPort();
540
      }
541
    catch (SocketException e)
542
      {
543
        // This cannot happen as we are connected.
544
      }
545
 
546
    return 0;
547
  }
548
 
549
  /**
550
   * Returns the local port number to which this socket is bound.  If this
551
   * socket is not connected, then -1 is returned.
552
   *
553
   * @return The local port
554
   */
555
  public int getLocalPort()
556
  {
557
    if (! isBound())
558
      return -1;
559
 
560
    try
561
      {
562
        if (getImpl() != null)
563
          return getImpl().getLocalPort();
564
      }
565
    catch (SocketException e)
566
      {
567
        // This cannot happen as we are bound.
568
      }
569
 
570
    return -1;
571
  }
572
 
573
  /**
574
   * Returns local socket address.
575
   *
576
   * @return the local socket address, null if not bound
577
   *
578
   * @since 1.4
579
   */
580
  public SocketAddress getLocalSocketAddress()
581
  {
582
    if (! isBound())
583
      return null;
584
 
585
    InetAddress addr = getLocalAddress();
586
 
587
    try
588
      {
589
        return new InetSocketAddress(addr, getImpl().getLocalPort());
590
      }
591
    catch (SocketException e)
592
      {
593
        // This cannot happen as we are bound.
594
        return null;
595
      }
596
  }
597
 
598
  /**
599
   * Returns the remote socket address.
600
   *
601
   * @return the remote socket address, null of not connected
602
   *
603
   * @since 1.4
604
   */
605
  public SocketAddress getRemoteSocketAddress()
606
  {
607
    if (! isConnected())
608
      return null;
609
 
610
    try
611
      {
612
        return new InetSocketAddress(getImpl().getInetAddress(),
613
                                     getImpl().getPort());
614
      }
615
    catch (SocketException e)
616
      {
617
        // This cannot happen as we are connected.
618
        return null;
619
      }
620
  }
621
 
622
  /**
623
   * Returns an InputStream for reading from this socket.
624
   *
625
   * @return The InputStream object
626
   *
627
   * @exception IOException If an error occurs or Socket is not connected
628
   */
629
  public InputStream getInputStream() throws IOException
630
  {
631
    if (isClosed())
632
      throw new SocketException("socket is closed");
633
 
634
    if (! isConnected())
635
      throw new IOException("not connected");
636
 
637
    return getImpl().getInputStream();
638
  }
639
 
640
  /**
641
   * Returns an OutputStream for writing to this socket.
642
   *
643
   * @return The OutputStream object
644
   *
645
   * @exception IOException If an error occurs or Socket is not connected
646
   */
647
  public OutputStream getOutputStream() throws IOException
648
  {
649
    if (isClosed())
650
      throw new SocketException("socket is closed");
651
 
652
    if (! isConnected())
653
      throw new IOException("not connected");
654
 
655
    return getImpl().getOutputStream();
656
  }
657
 
658
  /**
659
   * Sets the TCP_NODELAY option on the socket.
660
   *
661
   * @param on true to enable, false to disable
662
   *
663
   * @exception SocketException If an error occurs or Socket is not connected
664
   *
665
   * @since 1.1
666
   */
667
  public void setTcpNoDelay(boolean on) throws SocketException
668
  {
669
    if (isClosed())
670
      throw new SocketException("socket is closed");
671
 
672
    getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
673
  }
674
 
675
  /**
676
   * Tests whether or not the TCP_NODELAY option is set on the socket.
677
   * Returns true if enabled, false if disabled. When on it disables the
678
   * Nagle algorithm which means that packets are always send immediatly and
679
   * never merged together to reduce network trafic.
680
   *
681
   * @return Whether or not TCP_NODELAY is set
682
   *
683
   * @exception SocketException If an error occurs or Socket not connected
684
   *
685
   * @since 1.1
686
   */
687
  public boolean getTcpNoDelay() throws SocketException
688
  {
689
    if (isClosed())
690
      throw new SocketException("socket is closed");
691
 
692
    Object on = getImpl().getOption(SocketOptions.TCP_NODELAY);
693
 
694
    if (on instanceof Boolean)
695
      return (((Boolean) on).booleanValue());
696
    else
697
      throw new SocketException("Internal Error");
698
  }
699
 
700
  /**
701
   * Sets the value of the SO_LINGER option on the socket.  If the
702
   * SO_LINGER option is set on a socket and there is still data waiting to
703
   * be sent when the socket is closed, then the close operation will block
704
   * until either that data is delivered or until the timeout period
705
   * expires.  The linger interval is specified in hundreths of a second
706
   * (platform specific?)
707
   *
708
   * @param on true to enable SO_LINGER, false to disable
709
   * @param linger The SO_LINGER timeout in hundreths of a second or -1 if
710
   * SO_LINGER not set.
711
   *
712
   * @exception SocketException If an error occurs or Socket not connected
713
   * @exception IllegalArgumentException If linger is negative
714
   *
715
   * @since 1.1
716
   */
717
  public void setSoLinger(boolean on, int linger) throws SocketException
718
  {
719
    if (isClosed())
720
      throw new SocketException("socket is closed");
721
 
722
    if (on)
723
      {
724
        if (linger < 0)
725
          throw new IllegalArgumentException("SO_LINGER must be >= 0");
726
 
727
        if (linger > 65535)
728
          linger = 65535;
729
 
730
        getImpl().setOption(SocketOptions.SO_LINGER, Integer.valueOf(linger));
731
      }
732
    else
733
      getImpl().setOption(SocketOptions.SO_LINGER, Integer.valueOf(-1));
734
  }
735
 
736
  /**
737
   * Returns the value of the SO_LINGER option on the socket.  If the
738
   * SO_LINGER option is set on a socket and there is still data waiting to
739
   * be sent when the socket is closed, then the close operation will block
740
   * until either that data is delivered or until the timeout period
741
   * expires.  This method either returns the timeouts (in hundredths of
742
   * of a second (platform specific?)) if SO_LINGER is set, or -1 if
743
   * SO_LINGER is not set.
744
   *
745
   * @return The SO_LINGER timeout in hundreths of a second or -1
746
   * if SO_LINGER not set
747
   *
748
   * @exception SocketException If an error occurs or Socket is not connected
749
   *
750
   * @since 1.1
751
   */
752
  public int getSoLinger() throws SocketException
753
  {
754
    if (isClosed())
755
      throw new SocketException("socket is closed");
756
 
757
    Object linger = getImpl().getOption(SocketOptions.SO_LINGER);
758
 
759
    if (linger instanceof Integer)
760
      return (((Integer) linger).intValue());
761
    else
762
      return -1;
763
  }
764
 
765
  /**
766
   * Sends urgent data through the socket
767
   *
768
   * @param data The data to send.
769
   * Only the lowest eight bits of data are sent
770
   *
771
   * @exception IOException If an error occurs
772
   *
773
   * @since 1.4
774
   */
775
  public void sendUrgentData(int data) throws IOException
776
  {
777
    if (isClosed())
778
      throw new SocketException("socket is closed");
779
 
780
    getImpl().sendUrgentData(data);
781
  }
782
 
783
  /**
784
   * Enables/disables the SO_OOBINLINE option
785
   *
786
   * @param on True if SO_OOBLINE should be enabled
787
   *
788
   * @exception SocketException If an error occurs
789
   *
790
   * @since 1.4
791
   */
792
  public void setOOBInline(boolean on) throws SocketException
793
  {
794
    if (isClosed())
795
      throw new SocketException("socket is closed");
796
 
797
    getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
798
  }
799
 
800
  /**
801
   * Returns the current setting of the SO_OOBINLINE option for this socket
802
   *
803
   * @return True if SO_OOBINLINE is set, false otherwise.
804
   *
805
   * @exception SocketException If an error occurs
806
   *
807
   * @since 1.4
808
   */
809
  public boolean getOOBInline() throws SocketException
810
  {
811
    if (isClosed())
812
      throw new SocketException("socket is closed");
813
 
814
    Object buf = getImpl().getOption(SocketOptions.SO_OOBINLINE);
815
 
816
    if (buf instanceof Boolean)
817
      return (((Boolean) buf).booleanValue());
818
    else
819
      throw new SocketException("Internal Error: Unexpected type");
820
  }
821
 
822
  /**
823
   * Sets the value of the SO_TIMEOUT option on the socket.  If this value
824
   * is set, and an read/write is performed that does not complete within
825
   * the timeout period, a short count is returned (or an EWOULDBLOCK signal
826
   * would be sent in Unix if no data had been read).  A value of 0 for
827
   * this option implies that there is no timeout (ie, operations will
828
   * block forever).  On systems that have separate read and write timeout
829
   * values, this method returns the read timeout.  This
830
   * value is in milliseconds.
831
   *
832
   * @param timeout The length of the timeout in milliseconds, or
833
   * 0 to indicate no timeout.
834
   *
835
   * @exception SocketException If an error occurs or Socket not connected
836
   *
837
   * @since 1.1
838
   */
839
  public synchronized void setSoTimeout(int timeout) throws SocketException
840
  {
841
    if (isClosed())
842
      throw new SocketException("socket is closed");
843
 
844
    if (timeout < 0)
845
      throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
846
 
847
    getImpl().setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
848
  }
849
 
850
  /**
851
   * Returns the value of the SO_TIMEOUT option on the socket.  If this value
852
   * is set, and an read/write is performed that does not complete within
853
   * the timeout period, a short count is returned (or an EWOULDBLOCK signal
854
   * would be sent in Unix if no data had been read).  A value of 0 for
855
   * this option implies that there is no timeout (ie, operations will
856
   * block forever).  On systems that have separate read and write timeout
857
   * values, this method returns the read timeout.  This
858
   * value is in thousandths of a second (implementation specific?).
859
   *
860
   * @return The length of the timeout in thousandth's of a second or 0
861
   * if not set
862
   *
863
   * @exception SocketException If an error occurs or Socket not connected
864
   *
865
   * @since 1.1
866
   */
867
  public synchronized int getSoTimeout() throws SocketException
868
  {
869
    if (isClosed())
870
      throw new SocketException("socket is closed");
871
 
872
    Object timeout = getImpl().getOption(SocketOptions.SO_TIMEOUT);
873
    if (timeout instanceof Integer)
874
      return (((Integer) timeout).intValue());
875
    else
876
      return 0;
877
  }
878
 
879
  /**
880
   * This method sets the value for the system level socket option
881
   * SO_SNDBUF to the specified value.  Note that valid values for this
882
   * option are specific to a given operating system.
883
   *
884
   * @param size The new send buffer size.
885
   *
886
   * @exception SocketException If an error occurs or Socket not connected
887
   * @exception IllegalArgumentException If size is 0 or negative
888
   *
889
   * @since 1.2
890
   */
891
  public void setSendBufferSize(int size) throws SocketException
892
  {
893
    if (isClosed())
894
      throw new SocketException("socket is closed");
895
 
896
    if (size <= 0)
897
      throw new IllegalArgumentException("SO_SNDBUF value must be > 0");
898
 
899
    getImpl().setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
900
  }
901
 
902
  /**
903
   * This method returns the value of the system level socket option
904
   * SO_SNDBUF, which is used by the operating system to tune buffer
905
   * sizes for data transfers.
906
   *
907
   * @return The send buffer size.
908
   *
909
   * @exception SocketException If an error occurs or socket not connected
910
   *
911
   * @since 1.2
912
   */
913
  public int getSendBufferSize() throws SocketException
914
  {
915
    if (isClosed())
916
      throw new SocketException("socket is closed");
917
 
918
    Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF);
919
 
920
    if (buf instanceof Integer)
921
      return (((Integer) buf).intValue());
922
    else
923
      throw new SocketException("Internal Error: Unexpected type");
924
  }
925
 
926
  /**
927
   * This method sets the value for the system level socket option
928
   * SO_RCVBUF to the specified value.  Note that valid values for this
929
   * option are specific to a given operating system.
930
   *
931
   * @param size The new receive buffer size.
932
   *
933
   * @exception SocketException If an error occurs or Socket is not connected
934
   * @exception IllegalArgumentException If size is 0 or negative
935
   *
936
   * @since 1.2
937
   */
938
  public void setReceiveBufferSize(int size) throws SocketException
939
  {
940
    if (isClosed())
941
      throw new SocketException("socket is closed");
942
 
943
    if (size <= 0)
944
      throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
945
 
946
    getImpl().setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
947
  }
948
 
949
  /**
950
   * This method returns the value of the system level socket option
951
   * SO_RCVBUF, which is used by the operating system to tune buffer
952
   * sizes for data transfers.
953
   *
954
   * @return The receive buffer size.
955
   *
956
   * @exception SocketException If an error occurs or Socket is not connected
957
   *
958
   * @since 1.2
959
   */
960
  public int getReceiveBufferSize() throws SocketException
961
  {
962
    if (isClosed())
963
      throw new SocketException("socket is closed");
964
 
965
    Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF);
966
 
967
    if (buf instanceof Integer)
968
      return (((Integer) buf).intValue());
969
    else
970
      throw new SocketException("Internal Error: Unexpected type");
971
  }
972
 
973
  /**
974
   * This method sets the value for the socket level socket option
975
   * SO_KEEPALIVE.
976
   *
977
   * @param on True if SO_KEEPALIVE should be enabled
978
   *
979
   * @exception SocketException If an error occurs or Socket is not connected
980
   *
981
   * @since 1.3
982
   */
983
  public void setKeepAlive(boolean on) throws SocketException
984
  {
985
    if (isClosed())
986
      throw new SocketException("socket is closed");
987
 
988
    getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
989
  }
990
 
991
  /**
992
   * This method returns the value of the socket level socket option
993
   * SO_KEEPALIVE.
994
   *
995
   * @return The setting
996
   *
997
   * @exception SocketException If an error occurs or Socket is not connected
998
   *
999
   * @since 1.3
1000
   */
1001
  public boolean getKeepAlive() throws SocketException
1002
  {
1003
    if (isClosed())
1004
      throw new SocketException("socket is closed");
1005
 
1006
    Object buf = getImpl().getOption(SocketOptions.SO_KEEPALIVE);
1007
 
1008
    if (buf instanceof Boolean)
1009
      return (((Boolean) buf).booleanValue());
1010
    else
1011
      throw new SocketException("Internal Error: Unexpected type");
1012
  }
1013
 
1014
  /**
1015
   * Closes the socket.
1016
   *
1017
   * @exception IOException If an error occurs
1018
   */
1019
  public synchronized void close() throws IOException
1020
  {
1021
    if (isClosed())
1022
      return;
1023
 
1024
    impl.close();
1025
    impl = null;
1026
  }
1027
 
1028
  /**
1029
   * Converts this <code>Socket</code> to a <code>String</code>.
1030
   *
1031
   * @return The <code>String</code> representation of this <code>Socket</code>
1032
   */
1033
  public String toString()
1034
  {
1035
    try
1036
      {
1037
        if (isConnected())
1038
          return (super.toString()
1039
                  + " [addr=" + getImpl().getInetAddress() + ",port="
1040
                  + getImpl().getPort() + ",localport="
1041
                  + getImpl().getLocalPort() + "]");
1042
      }
1043
    catch (SocketException e)
1044
      {
1045
        // This cannot happen as we are connected.
1046
      }
1047
 
1048
    return super.toString() + " [unconnected]";
1049
  }
1050
 
1051
  /**
1052
   * Sets the <code>SocketImplFactory</code>.  This may be done only once per
1053
   * virtual machine.  Subsequent attempts will generate a
1054
   * <code>SocketException</code>.  Note that a <code>SecurityManager</code>
1055
   * check is made prior to setting the factory.  If
1056
   * insufficient privileges exist to set the factory, then an
1057
   * <code>IOException</code> will be thrown.
1058
   *
1059
   * @param fac the factory to set
1060
   *
1061
   * @exception SecurityException If the <code>SecurityManager</code> does
1062
   * not allow this operation.
1063
   * @exception SocketException If the SocketImplFactory is already defined
1064
   * @exception IOException If any other error occurs
1065
   */
1066
  public static synchronized void setSocketImplFactory(SocketImplFactory fac)
1067
    throws IOException
1068
  {
1069
    // See if already set
1070
    if (factory != null)
1071
      throw new SocketException("SocketImplFactory already defined");
1072
 
1073
    // Check permissions
1074
    SecurityManager sm = System.getSecurityManager();
1075
    if (sm != null)
1076
      sm.checkSetFactory();
1077
 
1078
    if (fac == null)
1079
      throw new SocketException("SocketImplFactory cannot be null");
1080
 
1081
    factory = fac;
1082
  }
1083
 
1084
  /**
1085
   * Closes the input side of the socket stream.
1086
   *
1087
   * @exception IOException If an error occurs.
1088
   *
1089
   * @since 1.3
1090
   */
1091
  public void shutdownInput() throws IOException
1092
  {
1093
    if (isClosed())
1094
      throw new SocketException("socket is closed");
1095
 
1096
    getImpl().shutdownInput();
1097
    inputShutdown = true;
1098
  }
1099
 
1100
  /**
1101
   * Closes the output side of the socket stream.
1102
   *
1103
   * @exception IOException If an error occurs.
1104
   *
1105
   * @since 1.3
1106
   */
1107
  public void shutdownOutput() throws IOException
1108
  {
1109
    if (isClosed())
1110
      throw new SocketException("socket is closed");
1111
 
1112
    getImpl().shutdownOutput();
1113
    outputShutdown = true;
1114
  }
1115
 
1116
  /**
1117
   * Returns the socket channel associated with this socket.
1118
   *
1119
   * @return the associated socket channel,
1120
   * null if no associated channel exists
1121
   *
1122
   * @since 1.4
1123
   */
1124
  public SocketChannel getChannel()
1125
  {
1126
    return null;
1127
  }
1128
 
1129
  /**
1130
   * Checks if the SO_REUSEADDR option is enabled
1131
   *
1132
   * @return True if SO_REUSEADDR is set, false otherwise.
1133
   *
1134
   * @exception SocketException If an error occurs
1135
   *
1136
   * @since 1.4
1137
   */
1138
  public boolean getReuseAddress() throws SocketException
1139
  {
1140
    if (isClosed())
1141
      throw new SocketException("socket is closed");
1142
 
1143
    Object reuseaddr = getImpl().getOption(SocketOptions.SO_REUSEADDR);
1144
 
1145
    if (! (reuseaddr instanceof Boolean))
1146
      throw new SocketException("Internal Error");
1147
 
1148
    return ((Boolean) reuseaddr).booleanValue();
1149
  }
1150
 
1151
  /**
1152
   * Enables/Disables the SO_REUSEADDR option
1153
   *
1154
   * @param reuseAddress true if SO_REUSEADDR should be enabled,
1155
   * false otherwise
1156
   *
1157
   * @exception SocketException If an error occurs
1158
   *
1159
   * @since 1.4
1160
   */
1161
  public void setReuseAddress(boolean reuseAddress) throws SocketException
1162
  {
1163
    if (isClosed())
1164
      throw new SocketException("socket is closed");
1165
 
1166
    getImpl().setOption(SocketOptions.SO_REUSEADDR,
1167
                        Boolean.valueOf(reuseAddress));
1168
  }
1169
 
1170
  /**
1171
   * Returns the current traffic class
1172
   *
1173
   * @return The current traffic class.
1174
   *
1175
   * @exception SocketException If an error occurs
1176
   *
1177
   * @see Socket#setTrafficClass(int tc)
1178
   *
1179
   * @since 1.4
1180
   */
1181
  public int getTrafficClass() throws SocketException
1182
  {
1183
    if (isClosed())
1184
      throw new SocketException("socket is closed");
1185
 
1186
    Object obj = getImpl().getOption(SocketOptions.IP_TOS);
1187
 
1188
    if (obj instanceof Integer)
1189
      return ((Integer) obj).intValue();
1190
    else
1191
      throw new SocketException("Unexpected type");
1192
  }
1193
 
1194
  /**
1195
   * Sets the traffic class value
1196
   *
1197
   * @param tc The traffic class
1198
   *
1199
   * @exception SocketException If an error occurs
1200
   * @exception IllegalArgumentException If tc value is illegal
1201
   *
1202
   * @see Socket#getTrafficClass()
1203
   *
1204
   * @since 1.4
1205
   */
1206
  public void setTrafficClass(int tc) throws SocketException
1207
  {
1208
    if (isClosed())
1209
      throw new SocketException("socket is closed");
1210
 
1211
    if (tc < 0 || tc > 255)
1212
      throw new IllegalArgumentException();
1213
 
1214
    getImpl().setOption(SocketOptions.IP_TOS, Integer.valueOf(tc));
1215
  }
1216
 
1217
  /**
1218
   * Checks if the socket is connected
1219
   *
1220
   * @return True if socket is connected, false otherwise.
1221
   *
1222
   * @since 1.4
1223
   */
1224
  public boolean isConnected()
1225
  {
1226
    if (impl == null)
1227
      return false;
1228
 
1229
    return impl.getInetAddress() != null;
1230
  }
1231
 
1232
  /**
1233
   * Checks if the socket is already bound.
1234
   *
1235
   * @return True if socket is bound, false otherwise.
1236
   *
1237
   * @since 1.4
1238
   */
1239
  public boolean isBound()
1240
  {
1241
    if (isClosed())
1242
      return false;
1243
    if (impl instanceof PlainSocketImpl)
1244
      {
1245
        InetSocketAddress addr = ((PlainSocketImpl) impl).getLocalAddress();
1246
        return addr != null && addr.getAddress() != null;
1247
      }
1248
    return bound;
1249
  }
1250
 
1251
  /**
1252
   * Checks if the socket is closed.
1253
   *
1254
   * @return True if socket is closed, false otherwise.
1255
   *
1256
   * @since 1.4
1257
   */
1258
  public boolean isClosed()
1259
  {
1260
    SocketChannel channel = getChannel();
1261
 
1262
    return impl == null || (channel != null && ! channel.isOpen());
1263
  }
1264
 
1265
  /**
1266
   * Checks if the socket's input stream is shutdown
1267
   *
1268
   * @return True if input is shut down.
1269
   *
1270
   * @since 1.4
1271
   */
1272
  public boolean isInputShutdown()
1273
  {
1274
    return inputShutdown;
1275
  }
1276
 
1277
  /**
1278
   * Checks if the socket's output stream is shutdown
1279
   *
1280
   * @return True if output is shut down.
1281
   *
1282
   * @since 1.4
1283
   */
1284
  public boolean isOutputShutdown()
1285
  {
1286
    return outputShutdown;
1287
  }
1288
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.