📄 serversocket.java
字号:
/* * @(#)ServerSocket.java 1.51 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package java.net;import java.io.FileDescriptor;import java.io.IOException;import java.security.AccessController;import java.security.PrivilegedExceptionAction;/** * This class implements server sockets. A server socket waits for * requests to come in over the network. It performs some operation * based on that request, and then possibly returns a result to the requester. * <p> * The actual work of the server socket is performed by an instance * of the <code>SocketImpl</code> class. An application can * change the socket factory that creates the socket * implementation to configure itself to create sockets * appropriate to the local firewall. * * @author unascribed * @version 1.43 10/17/00 * @see java.net.SocketImpl * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @since JDK1.0 */public class ServerSocket { /** * Various states of this socket. */ private boolean created = false; private boolean bound = false; private boolean closed = false; private Object closeLock = new Object(); /** * The implementation of this Socket. */ private SocketImpl impl; /** * Are we using an older SocketImpl? */ private boolean oldImpl = false; /** * Creates an unbound server socket. * * @exception IOException IO error when opening the socket. * @revised 1.4 */ public ServerSocket() throws IOException { setImpl(); } /** * Creates a server socket, bound to the specified port. A port of * <code>0</code> creates a socket on any free port. * <p> * The maximum queue length for incoming connection indications (a * request to connect) is set to <code>50</code>. If a connection * indication arrives when the queue is full, the connection is refused. * <p> * If the application has specified a server socket factory, that * factory's <code>createSocketImpl</code> method is called to create * the actual socket implementation. Otherwise a "plain" socket is created. * <p> * If there is a security manager, * its <code>checkListen</code> method is called * with the <code>port</code> argument * as its argument to ensure the operation is allowed. * This could result in a SecurityException. * * * @param port the port number, or <code>0</code> to use any * free port. * * @exception IOException if an I/O error occurs when opening the socket. * @exception SecurityException * if a security manager exists and its <code>checkListen</code> * method doesn't allow the operation. * * @see java.net.SocketImpl * @see java.net.SocketImplFactory#createSocketImpl() * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @see SecurityManager#checkListen */ public ServerSocket(int port) throws IOException { this(port, 50, null); } /** * Creates a server socket and binds it to the specified local port * number, with the specified backlog. * A port number of <code>0</code> creates a socket on any * free port. * <p> * The maximum queue length for incoming connection indications (a * request to connect) is set to the <code>backlog</code> parameter. If * a connection indication arrives when the queue is full, the * connection is refused. * <p> * If the application has specified a server socket factory, that * factory's <code>createSocketImpl</code> method is called to create * the actual socket implementation. Otherwise a "plain" socket is created. * <p> * If there is a security manager, * its <code>checkListen</code> method is called * with the <code>port</code> argument * as its argument to ensure the operation is allowed. * This could result in a SecurityException. * * <P>The <code>backlog</code> argument must be a positive * value greater than 0. If the value passed if equal or less * than 0, then the default value will be assumed. * <P> * * @param port the specified port, or <code>0</code> to use * any free port. * @param backlog the maximum length of the queue. * * @exception IOException if an I/O error occurs when opening the socket. * @exception SecurityException * if a security manager exists and its <code>checkListen</code> * method doesn't allow the operation. * * @see java.net.SocketImpl * @see java.net.SocketImplFactory#createSocketImpl() * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @see SecurityManager#checkListen */ public ServerSocket(int port, int backlog) throws IOException { this(port, backlog, null); } /** * Create a server with the specified port, listen backlog, and * local IP address to bind to. The <i>bindAddr</i> argument * can be used on a multi-homed host for a ServerSocket that * will only accept connect requests to one of its addresses. * If <i>bindAddr</i> is null, it will default accepting * connections on any/all local addresses. * The port must be between 0 and 65535, inclusive. * * <P>If there is a security manager, this method * calls its <code>checkListen</code> method * with the <code>port</code> argument * as its argument to ensure the operation is allowed. * This could result in a SecurityException. * * <P>The <code>backlog</code> argument must be a positive * value greater than 0. If the value passed if equal or less * than 0, then the default value will be assumed. * <P> * @param port the local TCP port * @param backlog the listen backlog * @param bindAddr the local InetAddress the server will bind to * * @throws SecurityException if a security manager exists and * its <code>checkListen</code> method doesn't allow the operation. * * @throws IOException if an I/O error occurs when opening the socket. * * @see SocketOptions * @see SocketImpl * @see SecurityManager#checkListen * @since JDK1.1 */ public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException { setImpl(); if (port < 0 || port > 0xFFFF) throw new IllegalArgumentException( "Port value out of range: " + port); if (backlog < 1) backlog = 50; try { bind(new InetSocketAddress(bindAddr, port), backlog); } catch(SecurityException e) { close(); throw e; } catch(IOException e) { close(); throw e; } } /** * Get the <code>SocketImpl</code> attached to this socket, creating * it if necessary. * * @return the <code>SocketImpl</code> attached to that ServerSocket. * @throws SocketException if creation fails. * @since 1.4 */ SocketImpl getImpl() throws SocketException { if (!created) createImpl(); return impl; } private void checkOldImpl() { if (impl == null) return; // SocketImpl.connect() is a protected method, therefore we need to use // getDeclaredMethod, therefore we need permission to access the member try { AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws NoSuchMethodException { Class[] cl = new Class[2]; cl[0] = SocketAddress.class; cl[1] = Integer.TYPE; impl.getClass().getDeclaredMethod("connect", cl); return null; } }); } catch (java.security.PrivilegedActionException e) { oldImpl = true; } } static Class implClass = null; private void setImpl() { if (factory != null) { impl = factory.createSocketImpl(); checkOldImpl(); } else { if (implClass == null) { try { String prefix = (String) AccessController.doPrivileged( new sun.security.action.GetPropertyAction("impl.prefix.stream", "Plain")); implClass = Class.forName("java.net."+prefix+"SocketImpl"); } catch (Exception e) { implClass = java.net.PlainSocketImpl.class; } } try { impl = (SocketImpl) implClass.newInstance(); } catch (Exception e) { impl = new PlainSocketImpl(); } if (impl != null && !(impl instanceof java.net.PlainSocketImpl)) checkOldImpl(); } if (impl != null) impl.setServerSocket(this); } /** * Creates the socket implementation. * * @throws IOException if creation fails * @since 1.4 */ void createImpl() throws SocketException { setImpl(); try { impl.create(true); created = true; } catch (IOException e) { throw new SocketException(e.getMessage()); } } /** * * Binds the <code>ServerSocket</code> to a specific address * (IP address and port number). * <p> * If the address is <code>null</code>, then the system will pick up * an ephemeral port and a valid local address to bind the socket. * <p> * @param endpoint The IP address & port number to bind to. * @throws IOException if the bind operation fails, or if the socket * is already bound. * @throws SecurityException if a <code>SecurityManager</code> is present and * its <code>checkListen</code> method doesn't allow the operation. * @throws IllegalArgumentException if endpoint is a * SocketAddress subclass not supported by this socket * @since 1.4 */ public void bind(SocketAddress endpoint) throws IOException { bind(endpoint, 50); } /** * * Binds the <code>ServerSocket</code> to a specific address * (IP address and port number). * <p> * If the address is <code>null</code>, then the system will pick up * an ephemeral port and a valid local address to bind the socket. * <P> * The <code>backlog</code> argument must be a positive * value greater than 0. If the value passed if equal or less * than 0, then the default value will be assumed. * @param endpoint The IP address & port number to bind to. * @param backlog The listen backlog length. * @throws IOException if the bind operation fails, or if the socket * is already bound. * @throws SecurityException if a <code>SecurityManager</code> is present and * its <code>checkListen</code> method doesn't allow the operation. * @throws IllegalArgumentException if endpoint is a * SocketAddress subclass not supported by this socket * @since 1.4 */ public void bind(SocketAddress endpoint, int backlog) throws IOException { if (isClosed()) throw new SocketException("Socket is closed"); if (!oldImpl && isBound()) throw new SocketException("Already bound"); if (endpoint == null) endpoint = new InetSocketAddress(0); if (!(endpoint instanceof InetSocketAddress)) throw new IllegalArgumentException("Unsupported address type"); InetSocketAddress epoint = (InetSocketAddress) endpoint; if (epoint.isUnresolved()) throw new SocketException("Unresolved address"); if (backlog < 1) backlog = 50; try { SecurityManager security = System.getSecurityManager(); if (security != null) security.checkListen(epoint.getPort()); getImpl().bind(epoint.getAddress(), epoint.getPort()); getImpl().listen(backlog); bound = true; } catch(SecurityException e) { bound = false; throw e; } catch(IOException e) { bound = false; throw e; } } /** * Returns the local address of this server socket. * * @return the address to which this socket is bound, * or <code>null</code> if the socket is unbound. */ public InetAddress getInetAddress() { if (!isBound()) return null; try { return getImpl().getInetAddress(); } catch (SocketException e) { // nothing // If we're bound, the the impl has been created // so we shouldn't get here } return null; } /** * Returns the port on which this socket is listening. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -