`
Donald_Draper
  • 浏览: 980147 次
社区版块
存档分类
最新评论

Mina Nio会话(Socket,DataGram)

    博客分类:
  • Mina
阅读更多
Mina Socket会话配置:http://donald-draper.iteye.com/blog/2375529
Mina 抽象Io会话:http://donald-draper.iteye.com/blog/2377880
引言:
    上一篇我们看了一下Io会话的抽象实现,先来回顾一下:
    抽象会话AbstractIoSession内部有一个关联的IoService和一个IoHandler;一个写请求队列用于存发会话写请求;一个会话属性Map存放会话属性,还有一些读写字节数,消息数,相关吞吐量和上次读写或空闲操作时间计数器。,会话初始化主要为初始化关联service,及关联的IoHandler,实际为Service的IoHandler;初始化所有的会话事件计数器为当前时间。关闭方法默认关闭时,清空写请求队列,并将写请求的结果置为已写,触发过滤过滤链fireFilterClose事件,即不flush会话写请求队列,closeOnFlush方法为,在关闭会话前,flush会话写请求队列。会话读操作,首先获取会话读请求结果队列,从队列poll一个读结果,如果读结果不为空且已关闭,则重新入队列,否则新建一个默认读请求结果,添加到会话等待读请求结果队列。会话写请求,首先保证消息不为null,会话建立连接,并且远端socket地址不为null;如果消息为IoBuffer,确保buffer不为空,如果消息为文件通道/文件类型,则包装消息为DefaultFileRegion/FilenameFileRegion;然后创建写请求DefaultWriteRequest,触发会话过滤链fireFilterWrite事件,如果消息为文件通道,则注册写结果监听器,在消息发送完后,关闭文件通道,返回写结果DefaultWriteFuture。
今天来看Io会话的具体实现传输层管理的会话NioSession
/**
 * An {@link IoSession} which is managed by the NIO transport.
 *  
 * @author [url=http://mina.apache.org]Apache MINA Project[/url]
 */
public abstract class NioSession extends AbstractIoSession {
    /** The NioSession processor */
    protected final IoProcessor<NioSession> processor;//会话关联Io处理器
    /** The communication channel */
    protected final Channel channel;//会话管理通道
    /** The SelectionKey used for this session */
    private SelectionKey key;//会话通道选择key
    /** The FilterChain created for this session */
    private final IoFilterChain filterChain;//会话过滤链
    /**
     * 
     * Creates a new instance of NioSession, with its associated IoProcessor.
     * <br>
     * This method is only called by the inherited class.
     *根据IO处理器,IoService,通道Channel构建nio会话
     * @param processor The associated {@link IoProcessor}
     * @param service The associated {@link IoService}
     * @param channel The associated {@link Channel}
     */
    protected NioSession(IoProcessor<NioSession> processor, IoService service, Channel channel) {
        super(service);
        this.channel = channel;
        this.processor = processor;
        filterChain = new DefaultIoFilterChain(this);
    }

    /**
     * @return The ByteChannel associated with this {@link IoSession} 
     获取会话通道
     */
    abstract ByteChannel getChannel();

    /**
     * {@inheritDoc}
     获取会话过滤链
     */
    @Override
    public IoFilterChain getFilterChain() {
        return filterChain;
    }

    /**
     * @return The {@link SelectionKey} associated with this {@link IoSession}
     获取会话选择key
     */
    /* No qualifier*/SelectionKey getSelectionKey() {
        return key;
    }

    /**
     * Sets the {@link SelectionKey} for this {@link IoSession}
     *设置会话选择key
     * @param key The new {@link SelectionKey}
     */
    /* No qualifier*/void setSelectionKey(SelectionKey key) {
        this.key = key;
    }

    /**
     * {@inheritDoc}
     获取会话关联Io处理器
     */
    @Override
    public IoProcessor<NioSession> getProcessor() {
        return processor;
    }

    /**
     * {@inheritDoc}
     会话是否处于激活状态
     */
    @Override
    public final boolean isActive() {
        return key.isValid();
    }
}

从上面可以看出,NioSession会话主要管理会话关联Io处理器processor,通道channel,
选择键SelectionKey和会话过滤链IoFilterChain;IoService交由AbstractIoSession管理。
下面来看socket会话NioSocketSession
/**
 * An {@link IoSession} for socket transport (TCP/IP).
 *
 * @author [url=http://mina.apache.org]Apache MINA Project[/url]
 */
class NioSocketSession extends NioSession {
   //Transport元数据
    static final TransportMetadata METADATA = new DefaultTransportMetadata("nio", "socket", false, true,
            InetSocketAddress.class, SocketSessionConfig.class, IoBuffer.class, FileRegion.class);
}
//默认Transport元数据
public class DefaultTransportMetadata
    implements TransportMetadata
{
    private final String providerName;//提供者名nio/aio/bio
    private final String name;//Transport元数据名
    private final boolean connectionless;//连接状态,(有连接的通信tcp,还是无连接udp)
    private final boolean fragmentation;//是否分片
    private final Class addressType;//地址类型
    private final Class sessionConfigType;//会话配置类型
    private final Set envelopeTypes;//涉及包装类型
    public transient DefaultTransportMetadata(String providerName, String name, boolean connectionless, 
                  boolean fragmentation, Class addressType, Class sessionConfigType, Class envelopeTypes[])
    {
    ...
    }
}

再来看socket会话的构造:
/**
 * 
 * Creates a new instance of NioSocketSession.
 *创建socket会话
 * @param service the associated IoService 
 * @param processor the associated IoProcessor
 * @param channel the used channel
 */
public NioSocketSession(IoService service, IoProcessor<NioSession> processor, SocketChannel channel) {
    super(processor, service, channel);
    config = new SessionConfigImpl();
    config.setAll(service.getSessionConfig());
}

从构造来看,socket会话配置继承于关联IoService的会话配置 ;
//获取会话socket
private Socket getSocket() {
    return ((SocketChannel) channel).socket();
}
/**
 * {@inheritDoc}
 获取传输元数据
 */
@Override
public TransportMetadata getTransportMetadata() {
    return METADATA;
}
/**
 * {@inheritDoc}
 获取socket会话配置
 */
@Override
public SocketSessionConfig getConfig() {
    return (SocketSessionConfig) config;
}
/**
 * {@inheritDoc}
 获取会话通道
 */
@Override
SocketChannel getChannel() {
    return (SocketChannel) channel;
}
/**
 * {@inheritDoc}
 获取会话远端地址
 */
@Override
public InetSocketAddress getRemoteAddress() {
    if (channel == null) {
        return null;
    }
    Socket socket = getSocket();
    if (socket == null) {
        return null;
    }
    return (InetSocketAddress) socket.getRemoteSocketAddress();
}
/**
 * {@inheritDoc}
 获取会话本地地址
 */
@Override
public InetSocketAddress getLocalAddress() {
    if (channel == null) {
        return null;
    }
    Socket socket = getSocket();
    if (socket == null) {
        return null;
    }
    return (InetSocketAddress) socket.getLocalSocketAddress();
}
//关闭会话,即取消会话关联的选择key和关闭关联通道。
protected void destroy(NioSession session) throws IOException {
    ByteChannel ch = session.getChannel();
    SelectionKey key = session.getSelectionKey();
    if (key != null) {
        key.cancel();
    }
    ch.close();
}
@Override
//获取会话关联Ioservice地址
public InetSocketAddress getServiceAddress() {
    return (InetSocketAddress) super.getServiceAddress();
}

回到构造函数中的会话配置:
public NioSocketSession(IoService service, IoProcessor<NioSession> processor, SocketChannel channel) {
    super(processor, service, channel);
    config = new SessionConfigImpl();
    config.setAll(service.getSessionConfig());
}

我们来看看一下SessionConfigImpl:
/**
     * A private class storing a copy of the IoService configuration when the IoSession
     * is created. That allows the session to have its own configuration setting, over
     * the IoService default one.
     SessionConfigImpl为socket会话私有类。当Io会话创建时,从关联IoService拷贝一份会话相关配置到
     当前会话。运行会话可以拥有自己的配置,覆盖从IoService继承的
     */
    private class SessionConfigImpl extends AbstractSocketSessionConfig {
       //下面这些配置,我们在前面已讲,这里不再重复,与socket配置基本相同
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isKeepAlive() {
            try {
                return getSocket().getKeepAlive();
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void setKeepAlive(boolean on) {
            try {
                getSocket().setKeepAlive(on);
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isOobInline() {
            try {
                return getSocket().getOOBInline();
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void setOobInline(boolean on) {
            try {
                getSocket().setOOBInline(on);
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isReuseAddress() {
            try {
                return getSocket().getReuseAddress();
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void setReuseAddress(boolean on) {
            try {
                getSocket().setReuseAddress(on);
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public int getSoLinger() {
            try {
                return getSocket().getSoLinger();
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void setSoLinger(int linger) {
            try {
                if (linger < 0) {
                    getSocket().setSoLinger(false, 0);
                } else {
                    getSocket().setSoLinger(true, linger);
                }
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isTcpNoDelay() {
            if (!isConnected()) {
                return false;
            }
            try {
                return getSocket().getTcpNoDelay();
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void setTcpNoDelay(boolean on) {
            try {
                getSocket().setTcpNoDelay(on);
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public int getTrafficClass() {
            try {
                return getSocket().getTrafficClass();
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void setTrafficClass(int tc) {
            try {
                getSocket().setTrafficClass(tc);
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public int getSendBufferSize() {
            try {
                return getSocket().getSendBufferSize();
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void setSendBufferSize(int size) {
            try {
                getSocket().setSendBufferSize(size);
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public int getReceiveBufferSize() {
            try {
                return getSocket().getReceiveBufferSize();
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void setReceiveBufferSize(int size) {
            try {
                getSocket().setReceiveBufferSize(size);
            } catch (SocketException e) {
                throw new RuntimeIoException(e);
            }
        }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean isSecured() {
        // If the session does not have a SslFilter, we can return false
        IoFilterChain chain = getFilterChain();
	//根据会话过滤链中是否添加SslFilter过滤器,来判断会话是否安全
        IoFilter sslFilter = chain.get(SslFilter.class);
        if (sslFilter != null) {
        // Get the SslHandler from the SslFilter
            return ((SslFilter)sslFilter).isSslStarted(this);
        } else {
            return false;
        }
    }
}

我们再来看一下报文会话:
class NioDatagramSession extends NioSession {
   //传输元数据
    static final TransportMetadata METADATA = new DefaultTransportMetadata("nio", "datagram", true, false,
            InetSocketAddress.class, DatagramSessionConfig.class, IoBuffer.class);
    private final InetSocketAddress localAddress;//本地地址
    private final InetSocketAddress remoteAddress;//远端地址
     /**
     * Creates a new connector-side session instance.
     创建一个单向连接的报文会话实例
     */
    NioDatagramSession(IoService service, DatagramChannel channel, IoProcessor<NioSession> processor) {
        this(service, channel, processor, channel.socket().getRemoteSocketAddress());
    }
    /**
     * Creates a new acceptor-side session instance.
     创建一个单向连接的报文会话实例
     */
    NioDatagramSession(IoService service, DatagramChannel channel, IoProcessor<NioSession> processor,
            SocketAddress remoteAddress) {
        super(processor, service, channel);
        config = new NioDatagramSessionConfig(channel);
        config.setAll(service.getSessionConfig());
        this.remoteAddress = (InetSocketAddress) remoteAddress;
        this.localAddress = (InetSocketAddress) channel.socket().getLocalSocketAddress();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public DatagramSessionConfig getConfig() {
        return (DatagramSessionConfig) config;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    DatagramChannel getChannel() {
        return (DatagramChannel) channel;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public TransportMetadata getTransportMetadata() {
        return METADATA;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public InetSocketAddress getRemoteAddress() {
        return remoteAddress;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public InetSocketAddress getLocalAddress() {
        return localAddress;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public InetSocketAddress getServiceAddress() {
        return (InetSocketAddress) super.getServiceAddress();
    }
}

总结:
   NioSession会话主要管理会话关联Io处理器processor,通道channel,选择键SelectionKey和会话过滤链IoFilterChain;IoService交由AbstractIoSession管理。
socket会话NioSocketSession配置继承于关联IoService的会话配置 ;关闭会话,即取消会话关联的选择key和关闭关联通道。

附:
public class DefaultTransportMetadata
    implements TransportMetadata
{
    private final String providerName;//提供者名nio/aio/bio
    private final String name;//Transport元数据名
    private final boolean connectionless;//连接状态,(有连接的通信tcp,还是无连接udp)
    private final boolean fragmentation;//是否分片
    private final Class addressType;//地址类型
    private final Class sessionConfigType;//会话配置类型
    private final Set envelopeTypes;//涉及包装类型
    public transient DefaultTransportMetadata(String providerName, String name, boolean connectionless, 
                  boolean fragmentation, Class addressType, Class sessionConfigType, Class envelopeTypes[])
    {
        
        if(providerName == null)
            throw new IllegalArgumentException("providerName");
        if(name == null)
            throw new IllegalArgumentException("name");
        providerName = providerName.trim().toLowerCase();
        if(providerName.length() == 0)
            throw new IllegalArgumentException("providerName is empty.");
        name = name.trim().toLowerCase();
        if(name.length() == 0)
            throw new IllegalArgumentException("name is empty.");
        if(addressType == null)
            throw new IllegalArgumentException("addressType");
        if(envelopeTypes == null)
            throw new IllegalArgumentException("envelopeTypes");
        if(envelopeTypes.length == 0)
            throw new IllegalArgumentException("envelopeTypes is empty.");
        if(sessionConfigType == null)
            throw new IllegalArgumentException("sessionConfigType");
        this.providerName = providerName;
        this.name = name;
        this.connectionless = connectionless;
        this.fragmentation = fragmentation;
        this.addressType = addressType;
        this.sessionConfigType = sessionConfigType;
        Set newEnvelopeTypes = new IdentityHashSet();
        Class aclass[] = envelopeTypes;
        int i = aclass.length;
        for(int j = 0; j < i; j++)
        {
            Class c = aclass[j];
            newEnvelopeTypes.add(c);
        }
        this.envelopeTypes = Collections.unmodifiableSet(newEnvelopeTypes);
    } 
}

下面这部分是报文会话配置,不做太多介绍:
//DatagramSessionConfig
/**
 * An {@link IoSessionConfig} for datagram transport type.
 *
 * @author The Apache Directory Project (mina-dev@directory.apache.org)
 * @version $Rev$, $Date$
 */
public interface DatagramSessionConfig extends IoSessionConfig {
    /**
     * @see DatagramSocket#getBroadcast()
     */
    boolean isBroadcast();

    /**
     * @see DatagramSocket#setBroadcast(boolean)
     */
    void setBroadcast(boolean broadcast);

    /**
     * @see DatagramSocket#getReuseAddress()
     */
    boolean isReuseAddress();

    /**
     * @see DatagramSocket#setReuseAddress(boolean)
     */
    void setReuseAddress(boolean reuseAddress);

    /**
     * @see DatagramSocket#getReceiveBufferSize()
     */
    int getReceiveBufferSize();

    /**
     * @see DatagramSocket#setReceiveBufferSize(int)
     */
    void setReceiveBufferSize(int receiveBufferSize);

    /**
     * @see DatagramSocket#getSendBufferSize()
     */
    int getSendBufferSize();

    /**
     * @see DatagramSocket#setSendBufferSize(int)
     */
    void setSendBufferSize(int sendBufferSize);

    /**
     * @see DatagramSocket#getTrafficClass()
     */
    int getTrafficClass();

    /**
     * @see DatagramSocket#setTrafficClass(int)
     */
    void setTrafficClass(int trafficClass);
}

//AbstractDatagramSessionConfig
/**
 * The Datagram transport session configuration.
 * 
 * @author [url=http://mina.apache.org]Apache MINA Project[/url]
 */
public abstract class AbstractDatagramSessionConfig extends AbstractIoSessionConfig implements DatagramSessionConfig {
    /** Tells if we should close the session if the port is unreachable. Default to true */
    private boolean closeOnPortUnreachable = true;

    /**
     * {@inheritDoc}
     */
    @Override
    public void setAll(IoSessionConfig config) {
        super.setAll(config);
        
        if (!(config instanceof DatagramSessionConfig)) {
            return;
        }

        if (config instanceof AbstractDatagramSessionConfig) {
            // Minimize unnecessary system calls by checking all 'propertyChanged' properties.
            AbstractDatagramSessionConfig cfg = (AbstractDatagramSessionConfig) config;
            
            if (cfg.isBroadcastChanged()) {
                setBroadcast(cfg.isBroadcast());
            }
            
            if (cfg.isReceiveBufferSizeChanged()) {
                setReceiveBufferSize(cfg.getReceiveBufferSize());
            }
            
            if (cfg.isReuseAddressChanged()) {
                setReuseAddress(cfg.isReuseAddress());
            }
            
            if (cfg.isSendBufferSizeChanged()) {
                setSendBufferSize(cfg.getSendBufferSize());
            }
            
            if (cfg.isTrafficClassChanged() && getTrafficClass() != cfg.getTrafficClass()) {
                setTrafficClass(cfg.getTrafficClass());
            }
        } else {
            DatagramSessionConfig cfg = (DatagramSessionConfig) config;
            setBroadcast(cfg.isBroadcast());
            setReceiveBufferSize(cfg.getReceiveBufferSize());
            setReuseAddress(cfg.isReuseAddress());
            setSendBufferSize(cfg.getSendBufferSize());
            
            if (getTrafficClass() != cfg.getTrafficClass()) {
                setTrafficClass(cfg.getTrafficClass());
            }
        }
    }

    /**
     * @return <tt>true</tt> if and only if the <tt>broadcast</tt> property
     * has been changed by its setter method.  The system call related with
     * the property is made only when this method returns <tt>true</tt>.  By
     * default, this method always returns <tt>true</tt> to simplify implementation
     * of subclasses, but overriding the default behavior is always encouraged.
     */
    protected boolean isBroadcastChanged() {
        return true;
    }

    /**
     * @return <tt>true</tt> if and only if the <tt>receiveBufferSize</tt> property
     * has been changed by its setter method.  The system call related with
     * the property is made only when this method returns <tt>true</tt>.  By
     * default, this method always returns <tt>true</tt> to simplify implementation
     * of subclasses, but overriding the default behavior is always encouraged.
     */
    protected boolean isReceiveBufferSizeChanged() {
        return true;
    }

    /**
     * @return <tt>true</tt> if and only if the <tt>reuseAddress</tt> property
     * has been changed by its setter method.  The system call related with
     * the property is made only when this method returns <tt>true</tt>.  By
     * default, this method always returns <tt>true</tt> to simplify implementation
     * of subclasses, but overriding the default behavior is always encouraged.
     */
    protected boolean isReuseAddressChanged() {
        return true;
    }

    /**
     * @return <tt>true</tt> if and only if the <tt>sendBufferSize</tt> property
     * has been changed by its setter method.  The system call related with
     * the property is made only when this method returns <tt>true</tt>.  By
     * default, this method always returns <tt>true</tt> to simplify implementation
     * of subclasses, but overriding the default behavior is always encouraged.
     */
    protected boolean isSendBufferSizeChanged() {
        return true;
    }

    /**
     * @return <tt>true</tt> if and only if the <tt>trafficClass</tt> property
     * has been changed by its setter method.  The system call related with
     * the property is made only when this method returns <tt>true</tt>.  By
     * default, this method always returns <tt>true</tt> to simplify implementation
     * of subclasses, but overriding the default behavior is always encouraged.
     */
    protected boolean isTrafficClassChanged() {
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isCloseOnPortUnreachable() {
        return closeOnPortUnreachable;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setCloseOnPortUnreachable(boolean closeOnPortUnreachable) {
        this.closeOnPortUnreachable = closeOnPortUnreachable;
    }
}

//NioDatagramSessionConfig
/**
 * Define the configuration for a Datagram based session. 
 * 
 * @author [url=http://mina.apache.org]Apache MINA Project[/url]
 */
class NioDatagramSessionConfig extends AbstractDatagramSessionConfig {
    /** The associated channel 关联报文通道*/
    private final DatagramChannel channel;

    /**
     * Creates a new instance of NioDatagramSessionConfig, associated
     * with the given DatagramChannel.
     *
     * @param channel The associated DatagramChannel
     */
    NioDatagramSessionConfig(DatagramChannel channel) {
        this.channel = channel;
    }

    /**
     * Get the Socket receive buffer size for this DatagramChannel.
     * 
     * @return the DatagramChannel receive buffer size.
     * @throws RuntimeIoException if the socket is closed or if we 
     * had a SocketException
     * 
     * @see DatagramSocket#getReceiveBufferSize()
     */
    @Override
    public int getReceiveBufferSize() {
        try {
            return channel.socket().getReceiveBufferSize();
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    /**
     * Set the Socket receive buffer size for this DatagramChannel. <br>
     * <br>
     * Note : The underlying Socket may not accept the new buffer's size.
     * The user has to check that the new value has been set. 
     * 
     * @param receiveBufferSize the DatagramChannel receive buffer size.
     * @throws RuntimeIoException if the socket is closed or if we 
     * had a SocketException
     * 
     * @see DatagramSocket#setReceiveBufferSize(int)
     */
    @Override
    public void setReceiveBufferSize(int receiveBufferSize) {
        try {
            channel.socket().setReceiveBufferSize(receiveBufferSize);
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    /**
     * Tells if SO_BROADCAST is enabled.
     * 
     * @return <tt>true</tt> if SO_BROADCAST is enabled
     * @throws RuntimeIoException If the socket is closed or if we get an
     * {@link SocketException} 
     */
    @Override
    public boolean isBroadcast() {
        try {
            return channel.socket().getBroadcast();
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    @Override
    public void setBroadcast(boolean broadcast) {
        try {
            channel.socket().setBroadcast(broadcast);
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    /**
     * 
     * @throws RuntimeIoException If the socket is closed or if we get an
     * {@link SocketException} 
     */
    @Override
    public int getSendBufferSize() {
        try {
            return channel.socket().getSendBufferSize();
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    /**
     * 
     * @throws RuntimeIoException If the socket is closed or if we get an
     * {@link SocketException} 
     */
    @Override
    public void setSendBufferSize(int sendBufferSize) {
        try {
            channel.socket().setSendBufferSize(sendBufferSize);
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    /**
     * Tells if SO_REUSEADDR is enabled.
     * 
     * @return <tt>true</tt> if SO_REUSEADDR is enabled
     * @throws RuntimeIoException If the socket is closed or if we get an
     * {@link SocketException} 
     */
    @Override
    public boolean isReuseAddress() {
        try {
            return channel.socket().getReuseAddress();
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    /**
     * 
     * @throws RuntimeIoException If the socket is closed or if we get an
     * {@link SocketException} 
     */
    @Override
    public void setReuseAddress(boolean reuseAddress) {
        try {
            channel.socket().setReuseAddress(reuseAddress);
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    /**
     * Get the current Traffic Class for this Socket, if any. As this is
     * not a mandatory feature, the returned value should be considered as 
     * a hint. 
     * 
     * @return The Traffic Class supported by this Socket
     * @throws RuntimeIoException If the socket is closed or if we get an
     * {@link SocketException} 
     */
    @Override
    public int getTrafficClass() {
        try {
            return channel.socket().getTrafficClass();
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }

    /**
     * {@inheritDoc}
     * @throws RuntimeIoException If the socket is closed or if we get an
     * {@link SocketException} 
     */
    @Override
    public void setTrafficClass(int trafficClass) {
        try {
            channel.socket().setTrafficClass(trafficClass);
        } catch (SocketException e) {
            throw new RuntimeIoException(e);
        }
    }
}


0
1
分享到:
评论

相关推荐

    一般Socket客户端与Mina NIO Socket客户端对比示例

    本文将通过一个对比实例,探讨一般Socket客户端与Mina NIO (Non-blocking I/O) Socket客户端的差异和特点,帮助开发者理解这两种技术在实际应用中的选择。 首先,普通Socket客户端基于BIO(Blocking I/O)模型,它...

    Mina NIO Socket

    《Mina NIO Socket:深度解析与应用》 在Java世界中,网络编程是一个不可或缺的部分,而Mina NIO(Non-blocking I/O)Socket库则是Java开发者实现高性能、高并发网络服务的重要工具。本文将深入探讨Mina NIO Socket...

    Mina+Socket通信

    import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MinaServer { public static void main(String[] args) throws Exception { IoAcceptor acceptor = new NioSocketAcceptor(); ...

    Java springboot 整合mina 框架,nio通讯基础教程,mina框架基础教程.zip

    Mina的核心组件包括IoSession(会话),管理连接状态和传输数据;IoFilter(过滤器),用于数据的预处理和后处理;IoHandler(处理器),处理实际的业务逻辑。通过Mina,开发者可以快速构建出可扩展、高性能的网络...

    apache mina socket实例

    mina简单示例,Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信...Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。

    Android-MinaSocket一款基于Mina的Socket长连接库

    1. **非阻塞I/O**:Mina采用NIO(Non-blocking I/O)模式,提高了并发性能,使得单个线程可以处理多个连接,减少了线程上下文切换的开销。 2. **事件驱动**:Mina使用事件驱动模型,当数据到达或发送时,会触发相应...

    网络编程(socket、NIO、mina)---demo

    在这个"网络编程(socket、NIO、mina)---demo"的主题中,我们将深入探讨三个关键概念:Socket编程、非阻塞I/O(Non-blocking I/O,简称NIO)以及Apache Mina框架。这些技术广泛应用于构建高性能、高并发的网络应用...

    基于 MINA 的 TLS/SSL NIO Socket 实现(二)

    在本篇博文中,我们将深入探讨如何利用Apache MINA库实现基于TLS/SSL的NIO(非阻塞I/O)Socket通信。MINA是一个高度可扩展的网络应用框架,广泛用于构建高性能、高并发的网络应用程序,如服务器端的TCP和UDP服务。...

    mina框架中socket使用,有服务端和客户端。

    mina框架是Apache组织开发的一个网络通信框架,它基于Java NIO(非阻塞I/O)构建,用于简化网络编程,尤其是TCP和UDP协议的应用开发。本项目提供了服务端和客户端的示例,使得开发者能够更好地理解和应用MINA框架。 ...

    mina框架中socket应用的简单小项目,包含了所需jar

    MINA是一个为高性能网络应用提供高度抽象的Java NIO框架,它简化了网络编程,尤其是TCP/IP和UDP/IP协议的使用。标题中提及的“所需jar”指的是为了运行这个项目所必需的第三方库文件,通常包括MINA框架本身和其他...

    mina 服务器socket客服端发消息

    本文将深入探讨如何使用Mina来实现一个服务器以及对应的Socket客户端,从而进行消息传递。 **Mina 框架介绍** Mina提供了一个高级抽象层,允许开发者用类似处理Java IO的方式处理NIO(非阻塞I/O)。它简化了网络...

    MINA NIO 高性能异步并发网络通讯框架

    Sun NIO 要高出约 10%)。由于这一系列的重大改进,使得 2.0.x 成为十分令人期待的一个版本 我们在惊叹 MINA 可以带来多么大便利的同时,还不得不为其卓越的性能而骄傲,据称使用MINA开发服务器程序的性能已经...

    MINA2 教程 socket

    MINA2提供了缓冲区(Buffer)和NIO非阻塞I/O支持,这些特性有助于提高网络通信的性能。通过合理配置缓冲区大小、选择合适的I/O模型,可以进一步优化系统的吞吐量和响应速度。 8. **编码解码器**: 编码解码器是...

    练练手,用mina2.0搭建一个nio客户端

    标题中的“练练手,用mina2.0搭建一个nio客户端”表明了本文将探讨如何使用Mina 2.0框架构建一个基于非阻塞I/O(NIO)的客户端应用。Mina是一个开源的Java框架,常用于开发高性能、高并发的网络通信应用,如TCP/IP和...

    Mina Socket 源代码

    **Mina Socket 源代码解析** Mina Socket 是 Apache Mina 项目的一部分,它是一个高性能、可扩展的网络通信框架。Mina 提供了一种简单的方式来构建网络应用,如服务器和客户端,支持多种协议,如 TCP/IP 和 UDP。在...

    niosocket及其开源框架MINA学习总结收集.pdf

    相比于传统的阻塞式socket,NIO降低了系统资源的消耗,MINA则进一步简化了NIO的使用,使得开发者能更专注于应用的业务逻辑。对于需要处理大量并发连接的网络应用,如聊天服务器、游戏服务器等,NIO 和 MINA 是理想的...

    socket通信,mina长连接通信

    1. **MINA架构**:MINA基于NIO(非阻塞I/O),利用Selector进行多路复用,可以在单个线程中处理多个连接,提高系统效率。 2. **长连接**:与传统的Socket短连接不同,长连接保持在客户端和服务器之间长时间打开,...

    MinaDemo.zip SpringBoot集成Socket通讯

    现在我们来详细探讨如何在SpringBoot项目中集成Mina进行Socket通讯,并结合myBatis进行数据交互。 首先,我们需要在SpringBoot项目中引入Mina的相关依赖。在`pom.xml`文件中添加Mina的依赖项,例如: ```xml ...

    原创nio socket mina+javascript+flash实现commet长连接网页聊天室

    【标题】"原创nio socket mina+javascript+flash实现commet长连接网页聊天室"揭示了一个基于Java NIO(Non-blocking I/O)的Socket通信框架Mina与JavaScript、Flash技术结合,实现COMET(Comet是使服务器向浏览器推...

Global site tag (gtag.js) - Google Analytics