天天看點

java nio SocketChannel源碼分析簡介構造函數,2個open方法,方法validOps,bind,setOption,shutdownInput/Output 方法socket,isConnected,isConnectionPending,connect,finishConnect,getRemoteAddress 方法3個read,3個write,getLocalAddress

目錄

簡介

構造函數,2個open方法,方法validOps,bind,setOption,shutdownInput/Output

方法socket,isConnected,isConnectionPending,connect,finishConnect,getRemoteAddress

方法3個read,3個write,getLocalAddress

簡介

package java.nio.channels;

import java.io.IOException;
import java.net.Socket;
import java.net.SocketOption;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;

/**
 * 面向流的連接配接套接字的可選通道。
 *
 * <p> 套接字通道是通過調用該類的open方法之一來建立的。
 * 為任意預先存在的套接字建立通道是不可能的。新建立的套接字通道已打開,但尚未連接配接。
 * 嘗試在未連接配接的通道上調用I/O操作将導緻抛出NotYetConnectedException。
 * 可以通過調用其connect方法來連接配接套接字通道;
 * 一旦連接配接,套接字通道将保持連接配接,直到關閉。
 * 套接字通道是否連接配接可以通過調用它的isConnected方法來确定。
 *
 * <p> 套接字通道支援非阻塞連接配接:
 * 可以建立一個套接字通道,
 * 建立遠端套接字連結的過程可以通過connect方法發起,稍後由finishConnect方法完成。
 * 連接配接操作是否正在進行可以通過調用isConnectionPending方法來确定。
 *
 * <p> 套接字通道支援異步關閉,這類似于Channel類中指定的異步關閉操作。
 * 如果一個線程關閉了套接字的輸入端,而另一個線程在套接字的通道上阻塞了讀操作,
 * 那麼阻塞線程中的read操作将在不讀取任何位元組的情況下完成,并傳回-1。
 * 如果套接字的輸出端被一個線程關閉,而另一個線程在套接字的通道上的寫操作中被阻塞,
 * 那麼被阻塞的線程将收到一個AsynchronousCloseException。
 *
 * <p> 套接字選項使用setOption方法進行配置。套接字通道支援以下選項:
 * <blockquote>
 * <table border summary="Socket options">
 *   <tr>
 *     <th>Option Name</th>
 *     <th>Description</th>
 *   </tr>
 *   <tr>
 *     <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
 *     <td> 發送緩沖區的大小 </td>
 *   </tr>
 *   <tr>
 *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
 *     <td> 接收緩沖區的大小 </td>
 *   </tr>
 *   <tr>
 *     <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td>
 *     <td> 保持連接配接處于連接配接狀态 </td>
 *   </tr>
 *   <tr>
 *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
 *     <td> 重用位址 </td>
 *   </tr>
 *   <tr>
 *     <td> {@link java.net.StandardSocketOptions#SO_LINGER SO_LINGER} </td>
 *     <td> 在關閉時,如果資料存在(當配置為阻塞模式時) </td>
 *   </tr>
 *   <tr>
 *     <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td>
 *     <td> 禁用Nagle算法 </td>
 *   </tr>
 * </table>
 * </blockquote>
 * 還可能支援其他(特定于實作的)選項。
 *
 * <p> 套接字通道對于多個并發線程來說是安全的。
 * 它們支援并發讀寫,盡管在任何給定的時間内最多有一個線程在讀,最多有一個線程在寫。
 * connect和finishConnect方法是互相同步的,當其中一個方法的調用正在進行時,嘗試發起讀寫操作将會阻塞,直到調用完成。</p>
 *
 * @author Mark Reinhold
 * @author JSR-51 Expert Group
 * @since 1.4
 */

public abstract class SocketChannel
    extends AbstractSelectableChannel
    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
           
java nio SocketChannel源碼分析簡介構造函數,2個open方法,方法validOps,bind,setOption,shutdownInput/Output 方法socket,isConnected,isConnectionPending,connect,finishConnect,getRemoteAddress 方法3個read,3個write,getLocalAddress
java nio SocketChannel源碼分析簡介構造函數,2個open方法,方法validOps,bind,setOption,shutdownInput/Output 方法socket,isConnected,isConnectionPending,connect,finishConnect,getRemoteAddress 方法3個read,3個write,getLocalAddress

構造函數,2個open方法,方法validOps,bind,setOption,shutdownInput/Output

/**
     * 建立執行個體
     *
     * @param  provider
     *         The provider that created this channel
     */
    protected SocketChannel(SelectorProvider provider) {
        super(provider);
    }

    /**
     * 打開套接字通道。
     *
     * <p> 新通道是通過調用系統範圍預設java.nio.channels.spi的SelectorProvider對象的openSocketChannel方法建立的。</p>
     *
     * @return  A new socket channel
     *
     * @throws  IOException
     *          If an I/O error occurs
     */
    public static SocketChannel open() throws IOException {
        return SelectorProvider.provider().openSocketChannel();
    }

    /**
     * 打開一個套接字通道并将其連接配接到一個遠端位址。
     *
     * <p> 這個友善的方法工作起來就像調用open()方法,在産生的套接字通道上調用connect方法,将其遠端傳遞,然後傳回該通道。 </p>
     *
     * @param  remote
     *         The remote address to which the new channel is to be connected
     *
     * @return  A new, and connected, socket channel
     *
     * @throws  AsynchronousCloseException
     *          If another thread closes this channel
     *          while the connect operation is in progress
     *
     * @throws  ClosedByInterruptException
     *          If another thread interrupts the current thread
     *          while the connect operation is in progress, thereby
     *          closing the channel and setting the current thread's
     *          interrupt status
     *
     * @throws  UnresolvedAddressException
     *          If the given remote address is not fully resolved
     *
     * @throws  UnsupportedAddressTypeException
     *          If the type of the given remote address is not supported
     *
     * @throws  SecurityException
     *          If a security manager has been installed
     *          and it does not permit access to the given remote endpoint
     *
     * @throws  IOException
     *          If some other I/O error occurs
     */
    public static SocketChannel open(SocketAddress remote)
        throws IOException
    {
        SocketChannel sc = open();
        try {
            sc.connect(remote);
        } catch (Throwable x) {
            try {
                sc.close();
            } catch (Throwable suppressed) {
                x.addSuppressed(suppressed);
            }
            throw x;
        }
        assert sc.isConnected();
        return sc;
    }

    /**
     * 傳回一個操作集,辨別此通道支援的操作。
     *
     * <p> 套接字通道支援連接配接、讀取和寫入,
     * 是以該方法傳回(SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE)。</p>
     *
     * @return  The valid-operation set
     */
    public final int validOps() {
        return (SelectionKey.OP_READ
                | SelectionKey.OP_WRITE
                | SelectionKey.OP_CONNECT);
    }


    // -- Socket-specific operations --

    /**
     * @throws  ConnectionPendingException
     *          If a non-blocking connect operation is already in progress on
     *          this channel
     * @throws  AlreadyBoundException               {@inheritDoc}
     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
     * @throws  ClosedChannelException              {@inheritDoc}
     * @throws  IOException                         {@inheritDoc}
     * @throws  SecurityException
     *          If a security manager has been installed and its
     *          {@link SecurityManager#checkListen checkListen} method denies
     *          the operation
     *
     * @since 1.7
     */
    @Override
    public abstract SocketChannel bind(SocketAddress local)
        throws IOException;

    /**
     * @throws  UnsupportedOperationException           {@inheritDoc}
     * @throws  IllegalArgumentException                {@inheritDoc}
     * @throws  ClosedChannelException                  {@inheritDoc}
     * @throws  IOException                             {@inheritDoc}
     *
     * @since 1.7
     */
    @Override
    public abstract <T> SocketChannel setOption(SocketOption<T> name, T value)
        throws IOException;

    /**
     * 在不關閉通道的情況下關閉讀取連接配接。
     *
     * <p> 一旦停止讀取,則在通道上進一步讀取将傳回-1,即流結束訓示。
     * 如果連接配接的輸入端已經關閉,則調用此方法沒有效果。
     *
     * @return  The channel
     *
     * @throws  NotYetConnectedException
     *          If this channel is not yet connected
     * @throws  ClosedChannelException
     *          If this channel is closed
     * @throws  IOException
     *          If some other I/O error occurs
     *
     * @since 1.7
     */
    public abstract SocketChannel shutdownInput() throws IOException;

    /**
     * 在不關閉通道的情況下關閉寫入連接配接。
     *
     * <p> 一旦因為寫入而關閉,那麼進一步嘗試寫入通道将抛出ClosedChannelException。
     * 如果連接配接的輸出端已經關閉,那麼調用這個方法沒有效果。
     *
     * @return  The channel
     *
     * @throws  NotYetConnectedException
     *          If this channel is not yet connected
     * @throws  ClosedChannelException
     *          If this channel is closed
     * @throws  IOException
     *          If some other I/O error occurs
     *
     * @since 1.7
     */
    public abstract SocketChannel shutdownOutput() throws IOException;
           

方法socket,isConnected,isConnectionPending,connect,finishConnect,getRemoteAddress

/**
     * 檢索與此通道關聯的套接字。
     *
     * <p> 傳回的對象不會聲明沒有在java.net.Socket類中聲明的任何公共方法。 </p>
     *
     * @return  A socket associated with this channel
     */
    public abstract Socket socket();

    /**
     * 判斷此通道的網絡套接字是否已連接配接。
     *
     * @return  <tt>true</tt> if, and only if, this channel's network socket
     *          is {@link #isOpen open} and connected
     */
    public abstract boolean isConnected();

    /**
     * 說明該通道上是否有正在進行的連接配接操作。
     *
     * @return  <tt>true</tt> if, and only if, a connection operation has been
     *          initiated on this channel but not yet completed by invoking the
     *          {@link #finishConnect finishConnect} method
     */
    public abstract boolean isConnectionPending();

    /**
     * 連接配接此通道的套接字。
     *
     * <p> 如果此通道處于非阻塞模式,則此方法的調用将啟動非阻塞連接配接操作。
     * 如果連接配接立即建立,就像本地連接配接一樣,那麼這個方法将傳回true。
     * 否則,該方法将傳回false,并且連接配接操作必須在稍後通過調用finishConnect方法來完成。
     *
     * <p> 如果此通道處于阻塞模式,則此方法的調用将阻塞,直到建立連接配接或發生I/O錯誤。
     *
     * <p> 此方法執行與java.net.Socket類完全相同的安全檢查。
     * 也就是說,如果已經安裝了安全管理器,那麼該方法将驗證其checkConnect方法是否允許連接配接到給定遠端端點的位址和端口号。
     *
     * <p> 這個方法可以在任何時候被調用。如果在此通道上的讀或寫操作被調用時,
     * 該方法的調用正在進行中,那麼該操作将首先阻塞,直到該調用完成。
     * 如果發起連接配接嘗試但失敗,也就是說,如果此方法的調用抛出一個檢查過的異常,則通道将被關閉。</p>
     *
     * @param  remote
     *         The remote address to which this channel is to be connected
     *
     * @return  <tt>true</tt> if a connection was established,
     *          <tt>false</tt> if this channel is in non-blocking mode
     *          and the connection operation is in progress
     *
     * @throws  AlreadyConnectedException
     *          If this channel is already connected
     *
     * @throws  ConnectionPendingException
     *          If a non-blocking connection operation is already in progress
     *          on this channel
     *
     * @throws  ClosedChannelException
     *          If this channel is closed
     *
     * @throws  AsynchronousCloseException
     *          If another thread closes this channel
     *          while the connect operation is in progress
     *
     * @throws  ClosedByInterruptException
     *          If another thread interrupts the current thread
     *          while the connect operation is in progress, thereby
     *          closing the channel and setting the current thread's
     *          interrupt status
     *
     * @throws  UnresolvedAddressException
     *          If the given remote address is not fully resolved
     *
     * @throws  UnsupportedAddressTypeException
     *          If the type of the given remote address is not supported
     *
     * @throws  SecurityException
     *          If a security manager has been installed
     *          and it does not permit access to the given remote endpoint
     *
     * @throws  IOException
     *          If some other I/O error occurs
     */
    public abstract boolean connect(SocketAddress remote) throws IOException;

    /**
     * 完成連接配接socket通道的過程。
     *
     * <p> 通過将socket通道置于非阻塞模式,然後調用其connect方法,可以啟動非阻塞連接配接操作。
     * 一旦建立了連接配接,或者嘗試失敗,套接字通道将變為可連接配接的,并且可能會調用此方法來完成連接配接序列。
     * 如果connection操作失敗,則調用此方法将要抛出适當的java.io.IOException。
     *
     * <p> 如果此通道已經連接配接,則此方法不會阻塞,并将立即傳回true。
     * 如果這個通道是非阻塞模式,那麼如果連接配接過程還沒有完成,這個方法将傳回false。
     * 如果此通道處于blocking模式,則此方法将阻塞,
     * 直到連接配接完成或失敗,并總是傳回true或抛出描述失敗的checked exception。
     *
     * <p> 這個方法可以在任何時候被調用。如果在此通道上的讀或寫操作被調用時,
     * 該方法的調用正在進行中,那麼該操作将首先阻塞,直到該調用完成。
     * 如果連接配接嘗試失敗,也就是說,如果這個方法的調用抛出一個檢查過的異常,那麼通道将被關閉。</p>
     *
     * @return  <tt>true</tt> if, and only if, this channel's socket is now
     *          connected
     *
     * @throws  NoConnectionPendingException
     *          If this channel is not connected and a connection operation
     *          has not been initiated
     *
     * @throws  ClosedChannelException
     *          If this channel is closed
     *
     * @throws  AsynchronousCloseException
     *          If another thread closes this channel
     *          while the connect operation is in progress
     *
     * @throws  ClosedByInterruptException
     *          If another thread interrupts the current thread
     *          while the connect operation is in progress, thereby
     *          closing the channel and setting the current thread's
     *          interrupt status
     *
     * @throws  IOException
     *          If some other I/O error occurs
     */
    public abstract boolean finishConnect() throws IOException;

    /**
     * 傳回此通道套接字連接配接到的遠端位址。
     *
     * <p> 如果通道被綁定并連接配接到Internet Protocol 套接字位址,那麼該方法的傳回值類型為java.net.InetSocketAddress。
     *
     * @return  The remote address; {@code null} if the channel's socket is not
     *          connected
     *
     * @throws  ClosedChannelException
     *          If the channel is closed
     * @throws  IOException
     *          If an I/O error occurs
     *
     * @since 1.7
     */
    public abstract SocketAddress getRemoteAddress() throws IOException;
           

方法3個read,3個write,getLocalAddress

// -- ByteChannel operations --

    /**
     * @throws  NotYetConnectedException
     *          If this channel is not yet connected
     */
    public abstract int read(ByteBuffer dst) throws IOException;

    /**
     * @throws  NotYetConnectedException
     *          If this channel is not yet connected
     */
    public abstract long read(ByteBuffer[] dsts, int offset, int length)
        throws IOException;

    /**
     * @throws  NotYetConnectedException
     *          If this channel is not yet connected
     */
    public final long read(ByteBuffer[] dsts) throws IOException {
        return read(dsts, 0, dsts.length);
    }

    /**
     * @throws  NotYetConnectedException
     *          If this channel is not yet connected
     */
    public abstract int write(ByteBuffer src) throws IOException;

    /**
     * @throws  NotYetConnectedException
     *          If this channel is not yet connected
     */
    public abstract long write(ByteBuffer[] srcs, int offset, int length)
        throws IOException;

    /**
     * @throws  NotYetConnectedException
     *          If this channel is not yet connected
     */
    public final long write(ByteBuffer[] srcs) throws IOException {
        return write(srcs, 0, srcs.length);
    }

    /**
     * {@inheritDoc}
     * <p>
     * 如果設定了安全管理器,則使用本地位址和-1作為參數調用其checkConnect方法,以檢視是否允許該操作。
     * 如果不允許該操作,則傳回一個表示環回位址和通道套接字的本地端口的SocketAddress。
     *
     * @return  The {@code SocketAddress} that the socket is bound to, or the
     *          {@code SocketAddress} representing the loopback address if
     *          denied by the security manager, or {@code null} if the
     *          channel's socket is not bound
     *
     * @throws  ClosedChannelException     {@inheritDoc}
     * @throws  IOException                {@inheritDoc}
     */
    @Override
    public abstract SocketAddress getLocalAddress() throws IOException;
           

繼續閱讀