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/] [ServerSocket.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* ServerSocket.java -- Class for implementing server side sockets
2
   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2006
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.nio.channels.IllegalBlockingModeException;
45
import java.nio.channels.ServerSocketChannel;
46
 
47
 
48
/* Written using on-line Java Platform 1.2 API Specification.
49
 * Status:  I believe all methods are implemented.
50
 */
51
 
52
/**
53
 * This class models server side sockets.  The basic model is that the
54
 * server socket is created and bound to some well known port.  It then
55
 * listens for and accepts connections.  At that point the client and
56
 * server sockets are ready to communicate with one another utilizing
57
 * whatever application layer protocol they desire.
58
 *
59
 * As with the <code>Socket</code> class, most instance methods of this class
60
 * simply redirect their calls to an implementation class.
61
 *
62
 * @author Aaron M. Renn (arenn@urbanophile.com)
63
 * @author Per Bothner (bothner@cygnus.com)
64
 */
65
public class ServerSocket
66
{
67
  /**
68
   * This is the user defined SocketImplFactory, if one is supplied
69
   */
70
  private static SocketImplFactory factory;
71
 
72
  /**
73
   * This is the SocketImp object to which most instance methods in this
74
   * class are redirected
75
   */
76
  private SocketImpl impl;
77
 
78
  /**
79
   * We need to retain the local address even after the socket is closed.
80
   */
81
  private InetSocketAddress local;
82
 
83
  /*
84
   * This constructor is only used by java.nio.
85
   */
86
 
87
  // FIXME: Workaround a bug in gcj.
88
  //ServerSocket (PlainSocketImpl impl) throws IOException
89
  ServerSocket(SocketImpl impl) throws IOException
90
  {
91
    if (impl == null)
92
      throw new NullPointerException("impl may not be null");
93
 
94
    this.impl = impl;
95
    this.impl.create(true);
96
  }
97
 
98
  /*
99
   * This method is only used by java.nio.
100
   */
101
 
102
  // FIXME: Workaround a bug in gcj.
103
  //PlainSocketImpl getImpl()
104
  SocketImpl getImpl()
105
  {
106
    return impl;
107
  }
108
 
109
  /**
110
   * Constructor that simply sets the implementation.
111
   *
112
   * @exception IOException If an error occurs
113
   *
114
   * @specnote This constructor is public since JDK 1.4
115
   */
116
  public ServerSocket() throws IOException
117
  {
118
    if (factory != null)
119
      impl = factory.createSocketImpl();
120
    else
121
      impl = new PlainSocketImpl();
122
 
123
    impl.create(true);
124
  }
125
 
126
  /**
127
   * Creates a server socket and binds it to the specified port.  If the
128
   * port number is 0, a random free port will be chosen.  The pending
129
   * connection queue on this socket will be set to 50.
130
   *
131
   * @param port The port number to bind to
132
   *
133
   * @exception IOException If an error occurs
134
   * @exception SecurityException If a security manager exists and its
135
   * checkListen method doesn't allow the operation
136
   */
137
  public ServerSocket(int port) throws IOException
138
  {
139
    this(port, 50);
140
  }
141
 
142
  /**
143
   * Creates a server socket and binds it to the specified port.  If the
144
   * port number is 0, a random free port will be chosen.  The pending
145
   * connection queue on this socket will be set to the value passed as
146
   * arg2.
147
   *
148
   * @param port The port number to bind to
149
   * @param backlog The length of the pending connection queue
150
   *
151
   * @exception IOException If an error occurs
152
   * @exception SecurityException If a security manager exists and its
153
   * checkListen method doesn't allow the operation
154
   */
155
  public ServerSocket(int port, int backlog) throws IOException
156
  {
157
    this(port, backlog, null);
158
  }
159
 
160
  /**
161
   * Creates a server socket and binds it to the specified port.  If the
162
   * port number is 0, a random free port will be chosen.  The pending
163
   * connection queue on this socket will be set to the value passed as
164
   * backlog.  The third argument specifies a particular local address to
165
   * bind t or null to bind to all local address.
166
   *
167
   * @param port The port number to bind to
168
   * @param backlog The length of the pending connection queue
169
   * @param bindAddr The address to bind to, or null to bind to all addresses
170
   *
171
   * @exception IOException If an error occurs
172
   * @exception SecurityException If a security manager exists and its
173
   * checkListen method doesn't allow the operation
174
   *
175
   * @since 1.1
176
   */
177
  public ServerSocket(int port, int backlog, InetAddress bindAddr)
178
    throws IOException
179
  {
180
    this();
181
 
182
    // bind/listen socket
183
    bind(new InetSocketAddress(bindAddr, port), backlog);
184
  }
185
 
186
  /**
187
   * Binds the server socket to a specified socket address
188
   *
189
   * @param endpoint The socket address to bind to
190
   *
191
   * @exception IOException If an error occurs
192
   * @exception IllegalArgumentException If address type is not supported
193
   * @exception SecurityException If a security manager exists and its
194
   * checkListen method doesn't allow the operation
195
   *
196
   * @since 1.4
197
   */
198
  public void bind(SocketAddress endpoint) throws IOException
199
  {
200
    bind(endpoint, 50);
201
  }
202
 
203
  /**
204
   * Binds the server socket to a specified socket address
205
   *
206
   * @param endpoint The socket address to bind to
207
   * @param backlog The length of the pending connection queue
208
   *
209
   * @exception IOException If an error occurs
210
   * @exception IllegalArgumentException If address type is not supported
211
   * @exception SecurityException If a security manager exists and its
212
   * checkListen method doesn't allow the operation
213
   *
214
   * @since 1.4
215
   */
216
  public void bind(SocketAddress endpoint, int backlog)
217
    throws IOException
218
  {
219
    if (isClosed())
220
      throw new SocketException("ServerSocket is closed");
221
 
222
    if (! (endpoint instanceof InetSocketAddress))
223
      throw new IllegalArgumentException("Address type not supported");
224
 
225
    InetSocketAddress tmp = (InetSocketAddress) endpoint;
226
 
227
    SecurityManager s = System.getSecurityManager();
228
    if (s != null)
229
      s.checkListen(tmp.getPort());
230
 
231
    InetAddress addr = tmp.getAddress();
232
 
233
    // Initialize addr with 0.0.0.0.
234
    if (addr == null)
235
      addr = InetAddress.ANY_IF;
236
 
237
    try
238
      {
239
        impl.bind(addr, tmp.getPort());
240
        impl.listen(backlog);
241
        local = new InetSocketAddress(
242
            (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR),
243
            impl.getLocalPort());
244
      }
245
    catch (IOException exception)
246
      {
247
        close();
248
        throw exception;
249
      }
250
    catch (RuntimeException exception)
251
      {
252
        close();
253
        throw exception;
254
      }
255
    catch (Error error)
256
      {
257
        close();
258
        throw error;
259
      }
260
  }
261
 
262
  /**
263
   * This method returns the local address to which this socket is bound
264
   *
265
   * @return The socket's local address
266
   */
267
  public InetAddress getInetAddress()
268
  {
269
    if (local == null)
270
      return null;
271
 
272
    return local.getAddress();
273
  }
274
 
275
  /**
276
   * This method returns the local port number to which this socket is bound
277
   *
278
   * @return The socket's port number
279
   */
280
  public int getLocalPort()
281
  {
282
    if (local == null)
283
      return -1;
284
 
285
    return local.getPort();
286
  }
287
 
288
  /**
289
   * Returns the local socket address
290
   *
291
   * @return the local socket address, null if not bound
292
   *
293
   * @since 1.4
294
   */
295
  public SocketAddress getLocalSocketAddress()
296
  {
297
    return local;
298
  }
299
 
300
  /**
301
   * Accepts a new connection and returns a connected <code>Socket</code>
302
   * instance representing that connection.  This method will block until a
303
   * connection is available.
304
   *
305
   * @return socket object for the just accepted connection
306
   *
307
   * @exception IOException If an error occurs
308
   * @exception SecurityException If a security manager exists and its
309
   * checkListen method doesn't allow the operation
310
   * @exception IllegalBlockingModeException If this socket has an associated
311
   * channel, and the channel is in non-blocking mode
312
   * @exception SocketTimeoutException If a timeout was previously set with
313
   * setSoTimeout and the timeout has been reached
314
   */
315
  public Socket accept() throws IOException
316
  {
317
    Socket socket = new Socket();
318
 
319
    try
320
      {
321
        implAccept(socket);
322
      }
323
    catch (IOException e)
324
      {
325
        try
326
          {
327
            socket.close();
328
          }
329
        catch (IOException e2)
330
          {
331
            // Ignore.
332
          }
333
 
334
        throw e;
335
      }
336
 
337
    return socket;
338
  }
339
 
340
  /**
341
   * This protected method is used to help subclasses override
342
   * <code>ServerSocket.accept()</code>.  The passed in socket will be
343
   * connected when this method returns.
344
   *
345
   * @param socket The socket that is used for the accepted connection
346
   *
347
   * @exception IOException If an error occurs
348
   * @exception IllegalBlockingModeException If this socket has an associated
349
   * channel, and the channel is in non-blocking mode
350
   *
351
   * @since 1.1
352
   */
353
  protected final void implAccept(Socket socket) throws IOException
354
  {
355
    if (isClosed())
356
      throw new SocketException("ServerSocket is closed");
357
 
358
    // FIXME: Add a security check to make sure we're allowed to 
359
    // connect to the remote host.
360
 
361
    // The Sun spec says that if we have an associated channel and
362
    // it is in non-blocking mode, we throw an IllegalBlockingModeException.
363
    // However, in our implementation if the channel itself initiated this
364
    // operation, then we must honor it regardless of its blocking mode.
365
    if (getChannel() != null && ! getChannel().isBlocking()
366
        && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
367
      throw new IllegalBlockingModeException();
368
 
369
    impl.accept(socket.impl);
370
    socket.implCreated = true;
371
    socket.bound = true;
372
  }
373
 
374
  /**
375
   * Closes this socket and stops listening for connections
376
   *
377
   * @exception IOException If an error occurs
378
   */
379
  public void close() throws IOException
380
  {
381
    if (isClosed())
382
      return;
383
 
384
    impl.close();
385
    impl = null;
386
 
387
    if (getChannel() != null)
388
      getChannel().close();
389
  }
390
 
391
  /**
392
   * Returns the unique <code>ServerSocketChannel</code> object
393
   * associated with this socket, if any.
394
   *
395
   * <p>The socket only has a <code>ServerSocketChannel</code> if its created
396
   * by <code>ServerSocketChannel.open()</code>.</p>
397
   *
398
   * @return the associated socket channel, null if none exists
399
   *
400
   * @since 1.4
401
   */
402
  public ServerSocketChannel getChannel()
403
  {
404
    return null;
405
  }
406
 
407
  /**
408
   * Returns true when the socket is bound, otherwise false
409
   *
410
   * @return true if socket is bound, false otherwise
411
   *
412
   * @since 1.4
413
   */
414
  public boolean isBound()
415
  {
416
    return local != null;
417
  }
418
 
419
  /**
420
   * Returns true if the socket is closed, otherwise false
421
   *
422
   * @return true if socket is closed, false otherwise
423
   *
424
   * @since 1.4
425
   */
426
  public boolean isClosed()
427
  {
428
    return impl == null;
429
  }
430
 
431
  /**
432
   * Sets the value of SO_TIMEOUT.  A value of 0 implies that SO_TIMEOUT is
433
   * disabled (ie, operations never time out).  This is the number of
434
   * milliseconds a socket operation can block before an
435
   * InterruptedIOException is thrown.
436
   *
437
   * @param timeout The new SO_TIMEOUT value
438
   *
439
   * @exception SocketException If an error occurs
440
   *
441
   * @since 1.1
442
   */
443
  public void setSoTimeout(int timeout) throws SocketException
444
  {
445
    if (isClosed())
446
      throw new SocketException("ServerSocket is closed");
447
 
448
    if (timeout < 0)
449
      throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
450
 
451
    impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
452
  }
453
 
454
  /**
455
   * Retrieves the current value of the SO_TIMEOUT setting.  A value of 0
456
   * implies that SO_TIMEOUT is disabled (ie, operations never time out).
457
   * This is the number of milliseconds a socket operation can block before
458
   * an InterruptedIOException is thrown.
459
   *
460
   * @return The value of SO_TIMEOUT
461
   *
462
   * @exception IOException If an error occurs
463
   *
464
   * @since 1.1
465
   */
466
  public int getSoTimeout() throws IOException
467
  {
468
    if (isClosed())
469
      throw new SocketException("ServerSocket is closed");
470
 
471
    Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);
472
 
473
    if (! (timeout instanceof Integer))
474
      throw new IOException("Internal Error");
475
 
476
    return ((Integer) timeout).intValue();
477
  }
478
 
479
  /**
480
   * Enables/Disables the SO_REUSEADDR option
481
   *
482
   * @param on true if SO_REUSEADDR should be enabled, false otherwise
483
   *
484
   * @exception SocketException If an error occurs
485
   *
486
   * @since 1.4
487
   */
488
  public void setReuseAddress(boolean on) throws SocketException
489
  {
490
    if (isClosed())
491
      throw new SocketException("ServerSocket is closed");
492
 
493
    impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
494
  }
495
 
496
  /**
497
   * Checks if the SO_REUSEADDR option is enabled
498
   *
499
   * @return true if SO_REUSEADDR is set, false otherwise
500
   *
501
   * @exception SocketException If an error occurs
502
   *
503
   * @since 1.4
504
   */
505
  public boolean getReuseAddress() throws SocketException
506
  {
507
    if (isClosed())
508
      throw new SocketException("ServerSocket is closed");
509
 
510
    Object reuseaddr = impl.getOption(SocketOptions.SO_REUSEADDR);
511
 
512
    if (! (reuseaddr instanceof Boolean))
513
      throw new SocketException("Internal Error");
514
 
515
    return ((Boolean) reuseaddr).booleanValue();
516
  }
517
 
518
  /**
519
   * This method sets the value for the system level socket option
520
   * SO_RCVBUF to the specified value.  Note that valid values for this
521
   * option are specific to a given operating system.
522
   *
523
   * @param size The new receive buffer size.
524
   *
525
   * @exception SocketException If an error occurs or Socket is not connected
526
   * @exception IllegalArgumentException If size is 0 or negative
527
   *
528
   * @since 1.4
529
   */
530
  public void setReceiveBufferSize(int size) throws SocketException
531
  {
532
    if (isClosed())
533
      throw new SocketException("ServerSocket is closed");
534
 
535
    if (size <= 0)
536
      throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
537
 
538
    impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size));
539
  }
540
 
541
  /**
542
   * This method returns the value of the system level socket option
543
   * SO_RCVBUF, which is used by the operating system to tune buffer
544
   * sizes for data transfers.
545
   *
546
   * @return The receive buffer size.
547
   *
548
   * @exception SocketException If an error occurs or Socket is not connected
549
   *
550
   * @since 1.4
551
   */
552
  public int getReceiveBufferSize() throws SocketException
553
  {
554
    if (isClosed())
555
      throw new SocketException("ServerSocket is closed");
556
 
557
    Object buf = impl.getOption(SocketOptions.SO_RCVBUF);
558
 
559
    if (! (buf instanceof Integer))
560
      throw new SocketException("Internal Error: Unexpected type");
561
 
562
    return ((Integer) buf).intValue();
563
  }
564
 
565
  /**
566
   * Returns the value of this socket as a <code>String</code>.
567
   *
568
   * @return This socket represented as a <code>String</code>.
569
   */
570
  public String toString()
571
  {
572
    if (! isBound())
573
      return "ServerSocket[unbound]";
574
 
575
    return ("ServerSocket[addr=" + getInetAddress() + ",port="
576
           + impl.getPort() + ",localport=" + impl.getLocalPort() + "]");
577
  }
578
 
579
  /**
580
   * Sets the <code>SocketImplFactory</code> for all
581
   * <code>ServerSocket</code>'s.  This may only be done
582
   * once per virtual machine.  Subsequent attempts will generate an
583
   * exception.  Note that a <code>SecurityManager</code> check is made prior
584
   * to setting the factory.  If insufficient privileges exist to set the
585
   * factory, an exception will be thrown
586
   *
587
   * @param fac the factory to set
588
   *
589
   * @exception SecurityException If this operation is not allowed by the
590
   * <code>SecurityManager</code>.
591
   * @exception SocketException If the factory object is already defined
592
   * @exception IOException If any other error occurs
593
   */
594
  public static synchronized void setSocketFactory(SocketImplFactory fac)
595
    throws IOException
596
  {
597
    factory = fac;
598
  }
599
}

powered by: WebSVN 2.1.0

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