📄 serversocket.java
字号:
* @return the port number to which this socket is listening or * -1 if the socket is not bound yet. */ public int getLocalPort() { if (!isBound()) return -1; try { return getImpl().getLocalPort(); } catch (SocketException e) { // nothing // If we're bound, the the impl has been created // so we shouldn't get here } return -1; } /** * Returns the address of the endpoint this socket is bound to, or * <code>null</code> if it is not bound yet. * * @return a <code>SocketAddress</code> representing the local endpoint of this * socket, or <code>null</code> if it is not bound yet. * @see #getInetAddress() * @see #getLocalPort() * @see #bind(SocketAddress) * @since 1.4 */ public SocketAddress getLocalSocketAddress() { if (!isBound()) return null; return new InetSocketAddress(getInetAddress(), getLocalPort()); } /** * Listens for a connection to be made to this socket and accepts * it. The method blocks until a connection is made. * * <p>A new Socket <code>s</code> is created and, if there * is a security manager, * the security manager's <code>checkAccept</code> method is called * with <code>s.getInetAddress().getHostAddress()</code> and * <code>s.getPort()</code> * as its arguments to ensure the operation is allowed. * This could result in a SecurityException. * * @exception IOException if an I/O error occurs when waiting for a * connection. * @exception SecurityException if a security manager exists and its * <code>checkListen</code> method doesn't allow the operation. * @exception SocketTimeoutException if a timeout was previously set with setSoTimeout and * the timeout has been reached. * * @return the new Socket * @see SecurityManager#checkAccept * @revised 1.4 * @spec JSR-51 */ public Socket accept() throws IOException { if (isClosed()) throw new SocketException("Socket is closed"); if (!isBound()) throw new SocketException("Socket is not bound yet"); Socket s = new Socket((SocketImpl) null); implAccept(s); return s; } /** * Subclasses of ServerSocket use this method to override accept() * to return their own subclass of socket. So a FooServerSocket * will typically hand this method an <i>empty</i> FooSocket. On * return from implAccept the FooSocket will be connected to a client. * * @param s the Socket * @throws IOException if an I/O error occurs when waiting * for a connection. * @since JDK1.1 * @revised 1.4 * @spec JSR-51 */ protected final void implAccept(Socket s) throws IOException { SocketImpl si = null; try { if (s.impl == null) s.setImpl(); si = s.impl; s.impl = null; si.address = new InetAddress(); si.fd = new FileDescriptor(); getImpl().accept(si); SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkAccept(si.getInetAddress().getHostAddress(), si.getPort()); } } catch (IOException e) { if (si != null) si.reset(); s.impl = si; throw e; } catch (SecurityException e) { if (si != null) si.reset(); s.impl = si; throw e; } s.impl = si; s.postAccept(); } /** * Closes this socket. * * Any thread currently blocked in {@link #accept()} will throw * a {@link SocketException}. * * @exception IOException if an I/O error occurs when closing the socket. * @revised 1.4 * @spec JSR-51 */ public void close() throws IOException { synchronized(closeLock) { if (isClosed()) return; if (created) impl.close(); closed = true; } } /** * Returns the binding state of the ServerSocket. * * @return true if the ServerSocket succesfuly bound to an address * @since 1.4 */ public boolean isBound() { // Before 1.3 ServerSockets were always bound during creation return bound || oldImpl; } /** * Returns the closed state of the ServerSocket. * * @return true if the socket has been closed * @since 1.4 */ public boolean isClosed() { synchronized(closeLock) { return closed; } } /** * Enable/disable SO_TIMEOUT with the specified timeout, in * milliseconds. With this option set to a non-zero timeout, * a call to accept() for this ServerSocket * will block for only this amount of time. If the timeout expires, * a <B>java.net.SocketTimeoutException</B> is raised, though the * ServerSocket is still valid. The option <B>must</B> be enabled * prior to entering the blocking operation to have effect. The * timeout must be > 0. * A timeout of zero is interpreted as an infinite timeout. * @param timeout the specified timeout, in milliseconds * @exception SocketException if there is an error in * the underlying protocol, such as a TCP error. * @since JDK1.1 * @see #getSoTimeout() */ public synchronized void setSoTimeout(int timeout) throws SocketException { if (isClosed()) throw new SocketException("Socket is closed"); getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout)); } /** * Retrive setting for SO_TIMEOUT. 0 returns implies that the * option is disabled (i.e., timeout of infinity). * @return the SO_TIMEOUT value * @exception IOException if an I/O error occurs * @since JDK1.1 * @see #setSoTimeout(int) */ public synchronized int getSoTimeout() throws IOException { if (isClosed()) throw new SocketException("Socket is closed"); Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); /* extra type safety */ if (o instanceof Integer) { return ((Integer) o).intValue(); } else { return 0; } } /** * Enable/disable the SO_REUSEADDR socket option. * <p> * When a TCP connection is closed the connection may remain * in a timeout state for a period of time after the connection * is closed (typically known as the <tt>TIME_WAIT</tt> state * or <tt>2MSL</tt> wait state). * For applications using a well known socket address or port * it may not be possible to bind a socket to the required * <tt>SocketAddress</tt> if there is a connection in the * timeout state involving the socket address or port. * <p> * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket * using {@link #bind(SocketAddress)} allows the socket to be * bound even though a previous connection is in a timeout * state. * <p> * When a <tt>ServerSocket</tt> is created the initial setting * of <tt>SO_REUSEADDR</tt> is not defined. Applications can * use {@link getReuseAddress()} to determine the initial * setting of <tt>SO_REUSEADDR</tt>. * <p> * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or * disabled after a socket is bound (See {@link #isBound()}) * is not defined. * * @param on whether to enable or disable the socket option * @exception SocketException if an error occurs enabling or * disabling the <tt>SO_RESUEADDR</tt> socket option, * or the socket is closed. * @since 1.4 * @see #getReuseAddress() * @see #bind(SocketAddress) * @see #isBound() * @see #isClosed() */ public void setReuseAddress(boolean on) throws SocketException { if (isClosed()) throw new SocketException("Socket is closed"); getImpl().setOption(SocketOptions.SO_REUSEADDR, new Boolean(on)); } /** * Tests if SO_REUSEADDR is enabled. * * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled. * @exception SocketException if there is an error * in the underlying protocol, such as a TCP error. * @since 1.4 * @see #setReuseAddress(boolean) */ public boolean getReuseAddress() throws SocketException { if (isClosed()) throw new SocketException("Socket is closed"); return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue(); } /** * Returns the implementation address and implementation port of * this socket as a <code>String</code>. * * @return a string representation of this socket. */ public String toString() { if (!isBound()) return "ServerSocket[unbound]"; return "ServerSocket[addr=" + impl.getInetAddress() + ",port=" + impl.getPort() + ",localport=" + impl.getLocalPort() + "]"; } void setBound() { bound = true; } void setCreated() { created = true; } /** * The factory for all server sockets. */ private static SocketImplFactory factory; /** * Sets the server socket implementation factory for the * application. The factory can be specified only once. * <p> * When an application creates a new server socket, the socket * implementation factory's <code>createSocketImpl</code> method is * called to create the actual socket implementation. * <p> * If there is a security manager, this method first calls * the security manager's <code>checkSetFactory</code> method * to ensure the operation is allowed. * This could result in a SecurityException. * * @param fac the desired factory. * @exception IOException if an I/O error occurs when setting the * socket factory. * @exception SocketException if the factory has already been defined. * @exception SecurityException if a security manager exists and its * <code>checkSetFactory</code> method doesn't allow the operation. * @see java.net.SocketImplFactory#createSocketImpl() * @see SecurityManager#checkSetFactory */ public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException { if (factory != null) { throw new SocketException("factory already defined"); } SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkSetFactory(); } factory = fac; } /** * Sets a default proposed value for the SO_RCVBUF option for sockets * accepted from this <tt>ServerSocket</tt>. The value actually set * in the accepted socket must be determined by calling * {@link Socket#getReceiveBufferSize()} after the socket * is returned by {@link #accept()}. * <p> * The value of SO_RCVBUF is used both to set the size of the internal * socket receive buffer, and to set the size of the TCP receive window * that is advertized to the remote peer. * <p> * It is possible to change the value subsequently, by calling * {@link Socket#setReceiveBufferSize(int)}. However, if the application * wishes to allow a receive window larger than 64K bytes, as defined by RFC1323 * then the proposed value must be set in the ServerSocket <B>before</B> * it is bound to a local address. This implies, that the ServerSocket must be * created with the no-argument constructor, then setReceiveBufferSize() must * be called and lastly the ServerSocket is bound to an address by calling bind(). * <p> * Failure to do this will not cause an error, and the buffer size may be set to the * requested value but the TCP receive window in sockets accepted from * this ServerSocket will be no larger than 64K bytes. * * @exception SocketException if there is an error * in the underlying protocol, such as a TCP error. * * @param size the size to which to set the receive buffer * size. This value must be greater than 0. * * @exception IllegalArgumentException if the * value is 0 or is negative. * * @since 1.4 * @see #getReceiveBufferSize */ public synchronized void setReceiveBufferSize (int size) throws SocketException { if (!(size > 0)) { throw new IllegalArgumentException("negative receive size"); } if (isClosed()) throw new SocketException("Socket is closed"); getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size)); } /** * Gets the value of the SO_RCVBUF option for this <tt>ServerSocket</tt>, * that is the proposed buffer size that will be used for Sockets accepted * from this <tt>ServerSocket</tt>. * * <p>Note, the value actually set in the accepted socket is determined by * calling {@link Socket#getReceiveBufferSize()}. * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>. * @exception SocketException if there is an error * in the underlying protocol, such as a TCP error. * @see #setReceiveBufferSize(int) * @since 1.4 */ public synchronized int getReceiveBufferSize() throws SocketException{ if (isClosed()) throw new SocketException("Socket is closed"); int result = 0; Object o = getImpl().getOption(SocketOptions.SO_RCVBUF); if (o instanceof Integer) { result = ((Integer)o).intValue(); } return result; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -