Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)
Frames | No Frames

Source for java.net.ServerSocket

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

AltStyle によって変換されたページ (->オリジナル) /