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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [net/] [Socket.java] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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