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

ServerSocketChannelImpl解析

    博客分类:
  • NIO
nio 
阅读更多
Channel接口定义:http://donald-draper.iteye.com/blog/2369111
AbstractInterruptibleChannel接口定义:http://donald-draper.iteye.com/blog/2369238
SelectableChannel接口定义:http://donald-draper.iteye.com/blog/2369317
SelectionKey定义:http://donald-draper.iteye.com/blog/2369499
SelectorProvider定义:http://donald-draper.iteye.com/blog/2369615
AbstractSelectableChannel定义:http://donald-draper.iteye.com/blog/2369742
NetworkChannel接口定义:http://donald-draper.iteye.com/blog/2369773
ServerSocketChannel定义:http://donald-draper.iteye.com/blog/2369836
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper):
http://donald-draper.iteye.com/blog/2370811
WindowsSelectorImpl解析二(选择操作,通道注册,通道反注册,选择器关闭等):
http://donald-draper.iteye.com/blog/2370862
在ServerSocketChannel定义这篇文章中,我们看了一下ServerSocketChannel的定义,ServerSocketChannel主要是绑定socket地址和监听通道连接请求。
今天先来看一下如何打开一个ServerSocketChannel,从ServerSocketChannel的
open方法开始:
public static ServerSocketChannel open() throws IOException {
       return SelectorProvider.provider().openServerSocketChannel();
}

看到这个方法是不是很熟悉,我们在SelectorProvider定义这篇文章中,有讲过SelectorProvider.provider()的加载SelectorProvider的实例过程:
我们直接贴过来:
//SelectorProvider
  
 public static SelectorProvider provider() {  
            synchronized (lock) {  
                if (provider != null)  
                    return provider;  
           //在与当前线程相同访问控制权限的环境中,加载SelectorProvider实例  
                return AccessController.doPrivileged(  
                    new PrivilegedAction<SelectorProvider>() {  
                        public SelectorProvider run() {  
                                if (loadProviderFromProperty())  
                        //获取系统配置的SelectorProvider  
                                    return provider;  
                                if (loadProviderAsService())  
                         //获取类加载路径下的SelectorProvider  
                                    return provider;  
                        //加载默认的SelectorProvider  
                                provider = sun.nio.ch.DefaultSelectorProvider.create();  
                                return provider;  
                            }  
                        });  
            }  
    }  


来看默认的DefaultSelectorProvider
//DefaultSelectorProvider
   
package sun.nio.ch;  
      
    import java.nio.channels.spi.SelectorProvider;  
      
    // Referenced classes of package sun.nio.ch:  
    //            WindowsSelectorProvider  
      
    public class DefaultSelectorProvider  
    {  
        private DefaultSelectorProvider()  
        {  
        }  
        public static SelectorProvider create()  
        {  
            //默认的WindowsSelectorProvider  
            return new WindowsSelectorProvider();  
        }  
    }  

再来看WindowsSelectorProvider
//WindowsSelectorProvider
  
 package sun.nio.ch;  
      
    import java.io.IOException;  
    import java.nio.channels.spi.AbstractSelector;  
      
    // Referenced classes of package sun.nio.ch:  
    //            SelectorProviderImpl, WindowsSelectorImpl  
      
    public class WindowsSelectorProvider extends SelectorProviderImpl  
    {  
      
        public WindowsSelectorProvider()  
        {  
        }  
        public AbstractSelector openSelector()  
            throws IOException  
        {  
           //默认的选择器实现类  
            return new WindowsSelectorImpl(this);  
        }  
    }  


再来看SelectorProviderImpl
//SelectorProviderImpl
 
  package sun.nio.ch;  
      
    import java.io.IOException;  
    import java.net.ProtocolFamily;  
    import java.nio.channels.*;  
    import java.nio.channels.spi.AbstractSelector;  
    import java.nio.channels.spi.SelectorProvider;  
      
    // Referenced classes of package sun.nio.ch:  
    //            DatagramChannelImpl, PipeImpl, ServerSocketChannelImpl, SocketChannelImpl  
      
    public abstract class SelectorProviderImpl extends SelectorProvider  
    {  
      
        public SelectorProviderImpl()  
        {  
        }  
        //打开一个报文通道  
        public DatagramChannel openDatagramChannel()  
            throws IOException  
        {  
            return new DatagramChannelImpl(this);  
        }  
        //根据协议,打开一个报文通道  
        public DatagramChannel openDatagramChannel(ProtocolFamily protocolfamily)  
            throws IOException  
        {  
            return new DatagramChannelImpl(this, protocolfamily);  
        }  
         //打开一个管道  
        public Pipe openPipe()  
            throws IOException  
        {  
            return new PipeImpl(this);  
        }  
       //打开一个选择器,待子类扩展  
        public abstract AbstractSelector openSelector()  
            throws IOException;  
       //打开一个监听socket通道  
        public ServerSocketChannel openServerSocketChannel()  
            throws IOException  
        {  
            return new ServerSocketChannelImpl(this);  
        }  
        //打开一个socket通道(连接)  
        public SocketChannel openSocketChannel()  
            throws IOException  
        {  
            return new SocketChannelImpl(this);  
        }  
}  

从上面可以看出open一个ServerSocketChannel实际上返回的是ServerSocketChannelImpl。
下面我们来看ServerSocketChannelImpl的socket地址绑定和连接监听和可选择通道的相关方法实现。
class ServerSocketChannelImpl extends ServerSocketChannel
    implements SelChImpl
{
    private static NativeDispatcher nd = new SocketDispatcher();//Socket分发器
    private final FileDescriptor fd;//文件描述
    private int fdVal;//文件描述的值
    private volatile long thread;//ServerSocket线程本地编号
    private final Object lock;//地址绑定,接受连接同步锁
    private final Object stateLock;//状态锁
    private static final int ST_UNINITIALIZED = -1;//未初始化
    private static final int ST_INUSE = 0;//正在使用中
    private static final int ST_KILLED = 1;//关闭状态
    private int state;//ServerSocket状态
    private SocketAddress localAddress;//绑定地址
    ServerSocket socket;//ServerSocket
    static final boolean $assertionsDisabled = !sun/nio/ch/ServerSocketChannelImpl.desiredAssertionStatus();
    static 
    {
        //加载nio和net资源库,我们在WindowsSelectorImpl相关文章中有讲
        Util.load();
        initIDs();
    }
    private static native void initIDs();
    
    ServerSocketChannelImpl(SelectorProvider selectorprovider)
        throws IOException
    {
        super(selectorprovider);
        thread = 0L;
        lock = new Object();
        stateLock = new Object();
        state = -1;//默认创建是的状态为未初始化
	//获取ServerSocket的文件描述符
        fd = Net.serverSocket(true);
	//获取文件描述的id
        fdVal = IOUtil.fdVal(fd);
        state = 0;
    }
    ServerSocketChannelImpl(SelectorProvider selectorprovider, FileDescriptor filedescriptor, boolean flag)
        throws IOException
    {
        super(selectorprovider);
        thread = 0L;
        lock = new Object();
        stateLock = new Object();
        state = -1;
        fd = filedescriptor;
        fdVal = IOUtil.fdVal(filedescriptor);
        state = 0;
        if(flag)
	     //如果使用本地地址,则获取本地地址
            localAddress = Net.localAddress(filedescriptor);
    }
}

初始化需要关注的是这几点,
1.
//获取ServerSocket的文件描述符
fd = Net.serverSocket(true);

2.
//获取文件描述的id       
fdVal = IOUtil.fdVal(fd);

3.
if(flag)
    //如果使用本地地址,则获取本地地址
    localAddress = Net.localAddress(filedescriptor);

分别来看
1.
//获取ServerSocket的文件描述符
fd = Net.serverSocket(true);

class Net
{
   private static volatile boolean checkedIPv6 = false;
    private static volatile boolean isIPv6Available;
    public static final int SHUT_RD = 0;//关闭读操作
    public static final int SHUT_WR = 1;//关闭写操作
    public static final int SHUT_RDWR = 2;//关闭读写操作
    static 
    {
        //加载nio和net资源库
        Util.load();
        initIDs();
    }
    private static native void initIDs();
    //默认协议
    static final ProtocolFamily UNSPEC = new ProtocolFamily() {
    public String name()
    {
        return "UNSPEC";
    }

    };
    //获取ServerSocket文件描述
    static FileDescriptor serverSocket(boolean flag)
    {
        return IOUtil.newFD(socket0(isIPv6Available(), flag, true));
    }
    private static native int socket0(boolean flag, boolean flag1, boolean flag2);
}

//IOUtil
class IOUtil
{
    static final int IOV_MAX = iovMax();
    static final boolean $assertionsDisabled = !sun/nio/ch/IOUtil.desiredAssertionStatus();
    static 
    {
        Util.load();
    }
    创建文件描述符
    static FileDescriptor newFD(int i)
    {
        FileDescriptor filedescriptor = new FileDescriptor();
        setfdVal(filedescriptor, i);
        return filedescriptor;
    }
}


2.
//获取文件描述的id      
fdVal = IOUtil.fdVal(fd);

//IOUtil
static native int fdVal(FileDescriptor filedescriptor);


3.
if(flag)
    //如果使用本地地址,则获取本地地址
    localAddress = Net.localAddress(filedescriptor);

//Net
static InetSocketAddress localAddress(FileDescriptor filedescriptor)
        throws IOException
{
    //根据local地址和port构造InetSocketAddress
    return new InetSocketAddress(localInetAddress(filedescriptor), localPort(filedescriptor));
}
 private static native int localPort(FileDescriptor filedescriptor)
     throws IOException;

 private static native InetAddress localInetAddress(FileDescriptor filedescriptor)
     throws IOException;

从上面来看,ServerSocketChannelImpl的初始化主要是初始化ServerSocket通道线程thread,地址绑定,接受连接同步锁,默认创建ServerSocketChannelImpl的状态为未初始化,文件描述和文件描述id,如果使用本地地址,则获取本地地址。
来看地址绑定方法
public ServerSocketChannel bind(SocketAddress socketaddress, int i)
        throws IOException
    {
        synchronized(lock)
        {
            if(!isOpen())
	       //如果socket关闭,则抛出ClosedChannelException
                throw new ClosedChannelException();
            if(isBound())
	        //如果已绑定,则抛出AlreadyBoundException
                throw new AlreadyBoundException();
	    //确定inetsocketaddress
            InetSocketAddress inetsocketaddress = socketaddress != null ? Net.checkAddress(socketaddress) : new InetSocketAddress(0);
            SecurityManager securitymanager = System.getSecurityManager();
            if(securitymanager != null)
	        //检查地址端口监听权限
                securitymanager.checkListen(inetsocketaddress.getPort());
	    //绑定前工作
            NetHooks.beforeTcpBind(fd, inetsocketaddress.getAddress(), inetsocketaddress.getPort());
	    //实际地址绑定
            Net.bind(fd, inetsocketaddress.getAddress(), inetsocketaddress.getPort());
	    //开启监听,如果参数i小于1,默认接受50个连接
            Net.listen(fd, i >= 1 ? i : 50);
            synchronized(stateLock)
            {
	        //更新ocalAddress
                localAddress = Net.localAddress(fd);
            }
        }
        return this;
    }

绑定方法中与几点要关注,
1.
if(isBound())
    //如果已绑定,则抛出AlreadyBoundException
    throw new AlreadyBoundException();

 public boolean isBound()
 {
     Object obj = stateLock;//同步stateLock
     JVM INSTR monitorenter ;//进入同步,try
     //地址不为空,则为已绑定
     return localAddress != null;
     Exception exception;//有异常,则抛出
     exception;
     throw exception;
 }

2.
//确定inetsocketaddress
InetSocketAddress inetsocketaddress = socketaddress != null ? Net.checkAddress(socketaddress) : new InetSocketAddress(0);

//Net
static InetSocketAddress checkAddress(SocketAddress socketaddress)
{
    if(socketaddress == null)//地址为空
        throw new NullPointerException();
    if(!(socketaddress instanceof InetSocketAddress))//非InetSocketAddress类型地址
        throw new UnsupportedAddressTypeException();
    InetSocketAddress inetsocketaddress = (InetSocketAddress)socketaddress;
    if(inetsocketaddress.isUnresolved())//地址不可识别
        throw new UnresolvedAddressException();
    InetAddress inetaddress = inetsocketaddress.getAddress();
    //非ip4和ip6地址
    if(!(inetaddress instanceof Inet4Address) && !(inetaddress instanceof Inet6Address))
        throw new IllegalArgumentException("Invalid address type");
    else
        return inetsocketaddress;
}

3.
//绑定前工作
NetHooks.beforeTcpBind(fd, inetsocketaddress.getAddress(), inetsocketaddress.getPort());

//NetHooks
package sun.net;

import java.io.FileDescriptor;
import java.io.IOException;
import java.net.InetAddress;
public final class NetHooks
{
    public NetHooks()
    {
    }
    //待扩展
    public static void beforeTcpBind(FileDescriptor filedescriptor, InetAddress inetaddress, int i)
        throws IOException
    {
    }
    public static void beforeTcpConnect(FileDescriptor filedescriptor, InetAddress inetaddress, int i)
        throws IOException
    {
    }
}

4.
//实际地址绑定
Net.bind(fd, inetsocketaddress.getAddress(), inetsocketaddress.getPort());

//Net
static void bind(FileDescriptor filedescriptor, InetAddress inetaddress, int i)
    throws IOException
{
    bind(UNSPEC, filedescriptor, inetaddress, i);
}
static void bind(ProtocolFamily protocolfamily, FileDescriptor filedescriptor, InetAddress inetaddress, int i)
    throws IOException
{
    boolean flag = isIPv6Available() && protocolfamily != StandardProtocolFamily.INET;
    bind0(flag, filedescriptor, inetaddress, i);
}
private static native void bind0(boolean flag, FileDescriptor filedescriptor, InetAddress inetaddress, int i)
        throws IOException;

5.
//开启监听,s如果参数i小于1,默认接受50个连接
Net.listen(fd, i >= 1 ? i : 50);

//Net
static native void listen(FileDescriptor filedescriptor, int i)
      throws IOException;

从上面可以看出,bind首先检查ServerSocket是否关闭,是否绑定地址,
如果既没有绑定也没关闭,则检查绑定的socketaddress是否正确或合法;
然后通过Net工具类的bind(native)和listen(native),完成实际的
ServerSocket地址绑定和开启监听,如果绑定是开启的参数小于1,则默认接受50个连接。
再来看接受连接方法:
 public SocketChannel accept()
        throws IOException
    {
        Object obj = lock;//同步lock锁
        JVM INSTR monitorenter ;//try
        int i;
        FileDescriptor filedescriptor;
        InetSocketAddress ainetsocketaddress[];
        if(!isOpen())
	    //通道关闭
            throw new ClosedChannelException();
        if(!isBound())
	    //为绑定地址
            throw new NotYetBoundException();
        Object obj1 = null;
        i = 0;
	//接受连接后创建SocketChannelImpl的文件描述
        filedescriptor = new FileDescriptor();
        ainetsocketaddress = new InetSocketAddress[1];
        SocketChannel socketchannel;
        begin();
        if(isOpen())
            break MISSING_BLOCK_LABEL_114;
        socketchannel = null;
        thread = 0L;
        end(i > 0);
        if(!$assertionsDisabled && !IOStatus.check(i))
            throw new AssertionError();
        return socketchannel;
	//获取本地线程数
        thread = NativeThread.current();
        do
	    //接受连接
            i = accept0(fd, filedescriptor, ainetsocketaddress);
        while(i == -3 && isOpen());
        thread = 0L;
        end(i > 0);
        if(!$assertionsDisabled && !IOStatus.check(i))
            throw new AssertionError();
        break MISSING_BLOCK_LABEL_233;
        Exception exception;
        exception;
        thread = 0L;
        end(i > 0);
        if(!$assertionsDisabled && !IOStatus.check(i))
            throw new AssertionError();
        else
            throw exception;
        if(i >= 1) goto _L2; else goto _L1
_L1:
        null;
        obj;
        JVM INSTR monitorexit ;
        return;
_L2:
        SocketChannelImpl socketchannelimpl;
	//接受连接的处理通道socketchannelimpl,默认为阻塞模式
        IOUtil.configureBlocking(filedescriptor, true);
        InetSocketAddress inetsocketaddress = ainetsocketaddress[0];
	//构建SocketChannelImpl,这个具体在SocketChannelImpl再说
        socketchannelimpl = new SocketChannelImpl(provider(), filedescriptor, inetsocketaddress);
        SecurityManager securitymanager = System.getSecurityManager();
        if(securitymanager != null)
            try
            {
	        //检查地址和port权限
                securitymanager.checkAccept(inetsocketaddress.getAddress().getHostAddress(), inetsocketaddress.getPort());
            }
            catch(SecurityException securityexception)
            {
                socketchannelimpl.close();
                throw securityexception;
            }
	//返回socketchannelimpl
        socketchannelimpl;
        obj;
        JVM INSTR monitorexit ;//退出try
        return;
        Exception exception1;//有异常,抛出
        exception1;
        throw exception1;
    }

连接方法中有几点要关注,
1.
//获取本地线程数
 thread = NativeThread.current();

package sun.nio.ch;
class NativeThread
{
    NativeThread()
    {
    }
    static long current()
    {
        return 0L;
    }
    static void signal(long l)
    {
    }
}

2.
do
    //接受连接
     i = accept0(fd, filedescriptor, ainetsocketaddress);
 while(i == -3 && isOpen());

//ServerSocketChannelImpl
 private native int accept0(FileDescriptor filedescriptor, FileDescriptor filedescriptor1, InetSocketAddress ainetsocketaddress[])
        throws IOException;

3.
SocketChannelImpl socketchannelimpl;
//接受连接的处理通道socketchannelimpl,默认为阻塞模式
IOUtil.configureBlocking(filedescriptor, true);
InetSocketAddress inetsocketaddress = ainetsocketaddress[0];
//构建SocketChannelImpl,这个具体在SocketChannelImpl再说
socketchannelimpl = new SocketChannelImpl(provider(), filedescriptor, inetsocketaddress);

//IOUtil
static native void configureBlocking(FileDescriptor filedescriptor, boolean flag)
    throws IOException;

从上面来看,accept方法主要是调用accept0(native)方法接受连接,并根据接受来接
文件描述的地址构造SocketChannelImpl,并返回。
再看ServerSocketChannelImpl的其他方法
//配置阻塞模式
protected void implConfigureBlocking(boolean flag)
     throws IOException
 {
     IOUtil.configureBlocking(fd, flag);
 }

支持的默认配置选项
 public final Set supportedOptions()
    {
        return DefaultOptionsHolder.defaultOptions;
    }

//DefaultOptionsHolder
private static class DefaultOptionsHolder
    {
         static final Set defaultOptions = defaultOptions();
        private static Set defaultOptions()
        {
            HashSet hashset = new HashSet(2);
            hashset.add(StandardSocketOptions.SO_RCVBUF);
            hashset.add(StandardSocketOptions.SO_REUSEADDR);
	    //返回不可修改的HashSet
            return Collections.unmodifiableSet(hashset);
        }
        private DefaultOptionsHolder()
        {
        }
    }

//StandardSocketOptions
//socket接受缓存大小
public static final SocketOption<Integer> SO_RCVBUF =
        new StdSocketOption<Integer>("SO_RCVBUF", Integer.class);
//是否可重用地址
public static final SocketOption<Boolean> SO_REUSEADDR =
        new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
//StdSocketOption
 private static class StdSocketOption<T> implements SocketOption<T> {
     private final String name;
     private final Class<T> type;
     StdSocketOption(String name, Class<T> type) {
         this.name = name;
         this.type = type;
     }
     @Override public String name() { return name; }
     @Override public Class<T> type() { return type; }
     @Override public String toString() { return name; }
 }

//设置选项的置为obj
public volatile NetworkChannel setOption(SocketOption socketoption, Object obj)
        throws IOException
    {
        return setOption(socketoption, obj);
    }
public ServerSocketChannel setOption(SocketOption socketoption, Object obj)
        throws IOException
    {
        if(socketoption == null)
            throw new NullPointerException();
	//非通道支持选项,则抛出UnsupportedOperationException
        if(!supportedOptions().contains(socketoption))
            throw new UnsupportedOperationException((new StringBuilder()).append("'").append(socketoption).append("' not supported").toString());
        Object obj1 = stateLock;//同步状态lock
        JVM INSTR monitorenter ;//try
        if(!isOpen())
            throw new ClosedChannelException();
        Net.setSocketOption(fd, Net.UNSPEC, socketoption, obj);
        return this;
        Exception exception;//异常,则抛出
        exception;
        throw exception;
    }

//Net
static void setSocketOption(FileDescriptor filedescriptor, ProtocolFamily protocolfamily, SocketOption socketoption, Object obj)
        throws IOException
    {
        if(obj == null)
            throw new IllegalArgumentException("Invalid option value");
        Class class1 = socketoption.type();
	//非整形和布尔型,则抛出断言错误
        if(class1 != java/lang/Integer && class1 != java/lang/Boolean)
            throw new AssertionError("Should not reach here");
        if(socketoption == StandardSocketOptions.SO_RCVBUF || socketoption == StandardSocketOptions.SO_SNDBUF)
        {    //判断接受和发送缓冲区大小
            int i = ((Integer)obj).intValue();
            if(i < 0)
                throw new IllegalArgumentException("Invalid send/receive buffer size");
        }
	//缓冲区有数据,延迟关闭socket的的时间
        if(socketoption == StandardSocketOptions.SO_LINGER)
        {
            int j = ((Integer)obj).intValue();
            if(j < 0)
                obj = Integer.valueOf(-1);
            if(j > 65535)
                obj = Integer.valueOf(65535);
        }
	//UDP单播
        if(socketoption == StandardSocketOptions.IP_TOS)
        {
            int k = ((Integer)obj).intValue();
            if(k < 0 || k > 255)
                throw new IllegalArgumentException("Invalid IP_TOS value");
        }
	//UDP多播
        if(socketoption == StandardSocketOptions.IP_MULTICAST_TTL)
        {
            int l = ((Integer)obj).intValue();
            if(l < 0 || l > 255)
                throw new IllegalArgumentException("Invalid TTL/hop value");
        }
        OptionKey optionkey = SocketOptionRegistry.findOption(socketoption, protocolfamily);
        if(optionkey == null)
            throw new AssertionError("Option not found");
        int i1;
	//转换配置参数值
        if(class1 == java/lang/Integer)
        {
            i1 = ((Integer)obj).intValue();
        } else
        {
            boolean flag = ((Boolean)obj).booleanValue();
            i1 = flag ? 1 : 0;
        }
        boolean flag1 = protocolfamily == UNSPEC;
	//设置文件描述符的值
        setIntOption0(filedescriptor, flag1, optionkey.level(), optionkey.name(), i1);
    }

    private static native void setIntOption0(FileDescriptor filedescriptor, boolean flag, int i, int j, int k)
        throws IOException;


//获取配置选项
 
  public Object getOption(SocketOption socketoption)
        throws IOException
    {
        if(socketoption == null)
            throw new NullPointerException();
	//非通道支持选项,则抛出UnsupportedOperationException
        if(!supportedOptions().contains(socketoption))
            throw new UnsupportedOperationException((new StringBuilder()).append("'").append(socketoption).append("' not supported").toString());
        Object obj = stateLock;//同步状态lock
        JVM INSTR monitorenter ;//try
        if(!isOpen())
            throw new ClosedChannelException();
	//委托给Net
        return Net.getSocketOption(fd, Net.UNSPEC, socketoption);
        Exception exception;//异常,则抛出
        exception;
        throw exception;
    }

//Net
 static Object getSocketOption(FileDescriptor filedescriptor, ProtocolFamily protocolfamily, SocketOption socketoption)
        throws IOException
    {
        Class class1 = socketoption.type();
	//非整形和布尔型,则抛出断言错误
        if(class1 != java/lang/Integer && class1 != java/lang/Boolean)
            throw new AssertionError("Should not reach here");
        OptionKey optionkey = SocketOptionRegistry.findOption(socketoption, protocolfamily);
        if(optionkey == null)
            throw new AssertionError("Option not found");
        boolean flag = protocolfamily == UNSPEC;
	//获取文件描述的选项配置
        int i = getIntOption0(filedescriptor, flag, optionkey.level(), optionkey.name());
        if(class1 == java/lang/Integer)
            return Integer.valueOf(i);
        else
            return i != 0 ? Boolean.TRUE : Boolean.FALSE;
    }
    private static native int getIntOption0(FileDescriptor filedescriptor, boolean flag, int i, int j)
        throws IOException;

再来看ServerSocketChannelImpl的其他方法
//获取绑定地址
public SocketAddress localAddress()
    {
        Object obj = stateLock;//同步状态锁
        JVM INSTR monitorenter ;//try
        return localAddress;
        Exception exception;//有异常,则抛出
        exception;
        throw exception;
    }
 //获取Socket
 public ServerSocket socket()
    {
        Object obj = stateLock;//同步状态锁
        JVM INSTR monitorenter ;//try
        if(socket == null)
	    //创建ServerSocket适配器
            socket = ServerSocketAdaptor.create(this);
        return socket;
        Exception exception;//有异常,则抛出
        exception;
        throw exception;
    }

//ServerSocketAdaptor,可简单理解为ServerSocketChannelImpl的代理
public class ServerSocketAdaptor extends ServerSocket
{
    private final ServerSocketChannelImpl ssc;
    private volatile int timeout;
    static final boolean $assertionsDisabled = !sun/nio/ch/ServerSocketAdaptor.desiredAssertionStatus();
    private ServerSocketAdaptor(ServerSocketChannelImpl serversocketchannelimpl)
        throws IOException
    {
        timeout = 0;
        ssc = serversocketchannelimpl;
    }
    //根据ServerSocketChannelImpl创建ServerSocketAdaptor
    public static ServerSocket create(ServerSocketChannelImpl serversocketchannelimpl)
    {
        return new ServerSocketAdaptor(serversocketchannelimpl);
        IOException ioexception;
        ioexception;
        throw new Error(ioexception);
    }
    //绑定地址
     public void bind(SocketAddress socketaddress, int i)
        throws IOException
    {
        if(socketaddress == null)
            socketaddress = new InetSocketAddress(0);
        try
        {
            ssc.bind(socketaddress, i);
        }
        catch(Exception exception)
        {
            Net.translateException(exception);
        }
    }
}




在往下看之前,先看一下ServerSocketChannelImpl的socket的分发器
private static NativeDispatcher nd = new SocketDispatcher();//Socket分发器

class SocketDispatcher extends NativeDispatcher
{

    SocketDispatcher()
    {
    }
      static 
    {
        //加载nio,net资源库
        Util.load();
    }
    //读操作
    int read(FileDescriptor filedescriptor, long l, int i)
        throws IOException
    {
        return read0(filedescriptor, l, i);
    }
     static native int read0(FileDescriptor filedescriptor, long l, int i)
        throws IOException;
    long readv(FileDescriptor filedescriptor, long l, int i)
        throws IOException
    {
        return readv0(filedescriptor, l, i);
    }
     static native long readv0(FileDescriptor filedescriptor, long l, int i)
        throws IOException;
   //写操作
    int write(FileDescriptor filedescriptor, long l, int i)
        throws IOException
    {
        return write0(filedescriptor, l, i);
    }
    static native int write0(FileDescriptor filedescriptor, long l, int i)
        throws IOException;
    long writev(FileDescriptor filedescriptor, long l, int i)
        throws IOException
    {
        return writev0(filedescriptor, l, i);
    }
      static native long writev0(FileDescriptor filedescriptor, long l, int i)
        throws IOException;
    //预关闭文件描述符
    void preClose(FileDescriptor filedescriptor)
        throws IOException
    {
        preClose0(filedescriptor);
    }
    static native void preClose0(FileDescriptor filedescriptor)
        throws IOException;
    //关闭文件描述
    void close(FileDescriptor filedescriptor)
        throws IOException
    {
        close0(filedescriptor);
    }
    static native void close0(FileDescriptor filedescriptor)
        throws IOException;
}

再来看ServerSocketChannelImpl的其他方法
//实际关闭选择通道方法
protected void implCloseSelectableChannel()
        throws IOException
    {
        synchronized(stateLock)//通不状态锁
        {
            if(state != 1)
	        //如果状态没关闭,则本地Socket预先关闭
                nd.preClose(fd);
            long l = thread;
            if(l != 0L)
	        //本地线程不为null,则通知关闭
                NativeThread.signal(l);
            if(!isRegistered())
	        //如果通道反注册,则kill
                kill();
        }
    }
//关闭文件描述
    public void kill()
        throws IOException
    {
label0:
        {
            synchronized(stateLock)
            {
                if(state != 1)
                    break label0;
            }
            return;
        }
        if(state != -1)
            break MISSING_BLOCK_LABEL_34;
        state = 1;//置通道状态为关闭
        obj;
        JVM INSTR monitorexit ;
        return;
	//如果断言开启,如果通道打开或已注册,抛出断言错误
        if(!$assertionsDisabled && (isOpen() || isRegistered()))
            throw new AssertionError();
	//本地分发器关闭文件描述
        nd.close(fd);
        state = 1;
        obj;
        JVM INSTR monitorexit ;//退出同步
          goto _L1
        exception;
        throw exception;
_L1:
    }
 //获取文件描述
     public FileDescriptor getFD()
    {
        return fd;
    }
 //获取文件描述值
    public int getFDVal()
    {
        return fdVal;
    }
 //设置兴趣操作事件
 public void translateAndSetInterestOps(int i, SelectionKeyImpl selectionkeyimpl)
    {
        int j = 0;
        if((i & 16) != 0)
            j |= 1;
        selectionkeyimpl.selector.putEventOps(selectionkeyimpl, j);
    }


//设置就绪操作事件集
 public boolean translateAndSetReadyOps(int i, SelectionKeyImpl selectionkeyimpl)
 {
     return translateReadyOps(i, 0, selectionkeyimpl);
 }
//更新就绪操作事件集
  public boolean translateAndUpdateReadyOps(int i, SelectionKeyImpl selectionkeyimpl)
 {
     return translateReadyOps(i, selectionkeyimpl.nioReadyOps(), selectionkeyimpl);
 }
 //根据就绪事件集当前状态j,设置就绪事件为i
  public boolean translateReadyOps(int i, int j, SelectionKeyImpl selectionkeyimpl)
    {
        int k = selectionkeyimpl.nioInterestOps();//兴趣事件集
        int l = selectionkeyimpl.nioReadyOps();//就绪事件集
        int i1 = j;
	//就绪事件为读1写4连接8,接受连接事件16,不是这四种事件,则返回false
        if((i & 32) != 0)
            return false;
	//8+16,接受连接,并建立连接
        if((i & 24) != 0)
        {
            i1 = k;
            selectionkeyimpl.nioReadyOps(i1);
            return (i1 & ~l) != 0;
        }
        if((i & 1) != 0 && (k & 16) != 0)
            i1 |= 16;//接受连接
        selectionkeyimpl.nioReadyOps(i1);
        return (i1 & ~l) != 0;
    }



总结:

ServerSocketChannelImpl的初始化主要是初始化ServerSocket通道线程thread,地址绑定,接受连接同步锁,默认创建ServerSocketChannelImpl的状态为未初始化,文件描述和文件描述id,如果使用本地地址,则获取本地地址。bind首先检查ServerSocket是否关闭,是否绑定地址,如果既没有绑定也没关闭,则检查绑定的socketaddress是否正确或合法;然后通过Net工具类的bind(native)和listen(native),完成实际的ServerSocket地址绑定和开启监听,如果绑定是开启的参数小于1,则默认接受50个连接。accept方法主要是调用accept0(native)方法接受连接,并根据接受来接
文件描述的地址构造SocketChannelImpl,并返回。

附:
//NativeDispatcher
package sun.nio.ch;
import java.io.FileDescriptor;
import java.io.IOException;

abstract class NativeDispatcher
{

    NativeDispatcher()
    {
    }
    abstract void close(FileDescriptor filedescriptor)
        throws IOException;

    void preClose(FileDescriptor filedescriptor)
        throws IOException
    {
    }
    abstract int read(FileDescriptor filedescriptor, long l, int i)
        throws IOException;

    int pread(FileDescriptor filedescriptor, long l, int i, long l1, Object obj)
        throws IOException
    {
        throw new IOException("Operation Unsupported");
    }
    abstract long readv(FileDescriptor filedescriptor, long l, int i)
        throws IOException;

    abstract int write(FileDescriptor filedescriptor, long l, int i)
        throws IOException;
    int pwrite(FileDescriptor filedescriptor, long l, int i, long l1, Object obj)
        throws IOException
    {
        throw new IOException("Operation Unsupported");
    }
    abstract long writev(FileDescriptor filedescriptor, long l, int i)
        throws IOException;
}
  • 大小: 49.6 KB
0
1
分享到:
评论

相关推荐

    基于分时电价机制的家庭能量管理策略优化研究:考虑空调、电动汽车及可平移负荷的精细控制模型,基于分时电价机制的家庭能量管理策略优化研究:集成空调、电动汽车与可平移负荷管理模型,MATLAB代码:基于分时

    基于分时电价机制的家庭能量管理策略优化研究:考虑空调、电动汽车及可平移负荷的精细控制模型,基于分时电价机制的家庭能量管理策略优化研究:集成空调、电动汽车与可平移负荷管理模型,MATLAB代码:基于分时电价条件下家庭能量管理策略研究 关键词:家庭能量管理模型 分时电价 空调 电动汽车 可平移负荷 参考文档:《基于分时电价和蓄电池实时控制策略的家庭能量系统优化》参考部分模型 《计及舒适度的家庭能量管理系统优化控制策略》参考部分模型 仿真平台:MATLAB+CPLEX 平台 优势:代码具有一定的深度和创新性,注释清晰,非烂大街的代码,非常精品 主要内容:代码主要做的是家庭能量管理模型,首先构建了电动汽车、空调、热水器以及烘干机等若干家庭用户用电设备的能量管理模型,其次,考虑在分时电价、动态电价以及动态电价下休息日和工作日家庭用户的最优能量管理策略,依次通过CPLEX完成不同场景下居民用电策略的优化,该代码适合新手学习以及在此基础上进行拓展 ,核心关键词: 家庭能量管理模型; 分时电价; 电动汽车; 空调; 可平移负荷; 优化控制策略; 仿真平台(MATLAB+CPLEX); 深度创新性。,

    Delphi 12 控件之Winsoft PDFium Component Suite v7.4 for Delphi & CB 5-12 Athens Full Source.7z

    Winsoft PDFium Component Suite v7.4 for Delphi & CB 5-12 Athens Full Source.7z

    基于Matlab的草原生态管理策略研究:数学建模及E前四问问题分析思路,基于Matlab的草原放牧策略研究:数学建模与问题解决的前四问思路,基于Matlab的草原放牧的策略研究数学建模E前四问思路

    基于Matlab的草原生态管理策略研究:数学建模及E前四问问题分析思路,基于Matlab的草原放牧策略研究:数学建模与问题解决的前四问思路,基于Matlab的草原放牧的策略研究数学建模E前四问思路 ,基于Matlab的草原放牧策略研究; 数学建模; E前四问思路; 策略优化; 模型验证; 数据模拟。,Matlab草原放牧策略研究:数学建模E及前四问解析

    JSP基于SSH2新闻发布系统.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款,质量优质,放心下载使用

    LanSee175(局域网查看工具)

    主要功能 信息搜索:可快速搜索局域网中的计算机,获取计算机名、IP 地址、MAC 地址、所在工作组、用户等详细信息,还能搜索共享资源和共享文件,便于用户快速定位和访问所需资源。 网络嗅探:能够捕获 TCP、UDP、ICMP、ARP 等各种数据包,可嗅探局域网上的 QQ 号,查看各主机流量,还能从流过网卡的数据中嗅探出音乐、视频、图片等文件,帮助用户了解网络数据传输情况。 聊天与共享:具备局域网聊天和文件共享功能,无需服务器支持。用户可进行群聊或私聊,还能指定条件搜索其他用户共享的文件,方便局域网内的信息交流与资源共享。 计算机管理:可以向开启信使服务的计算机发送短消息,对于有相应权限的计算机,还能进行远程关闭或重启操作,方便网络管理员进行集中管理。 文件复制:支持复制网上邻居上的共享文件、LanSee 用户共享的文件以及通过网络嗅探功能嗅探出的文件,并且支持断点传输,提高文件复制的效率和稳定性。 端口与连接查看:可列出进程打开的所有网络端口以及连接情况,能快速扫描 TCP 端口,查看适配器信息,还能进行 Ping、Traceroute 等操作,帮助用户了解网络连接状态和诊断网络问题。

    迅雷软件下载原理介绍.md

    迅雷软件下载原理介绍.md

    最新更新!!!2024年HS编码出口退税率数据(2004-2024年)

    ## 01、数据简介 出口退税率是针对出口产品在国内已缴纳的税款,在货物报关出口后退还给出口企业时,按照一定比例计算的退税金额与计税价格之间的比率。 出口退税率是出口退税制度中的一个重要参数,它体现了国家对出口企业的税收优惠政策,有助于降低企业的出口成本,提升其在国际市场上的竞争力。同时,国家也会根据经济形势和国际贸易的变化,适时调整出口退税率,以更好地服务于国家的经济发展战略。 数据名称:2024年HS编码出口退税率数据 数据年份:2004-2024年 ## 02、相关数据 CODE、ST_DATE、END_DATE、ZHCMCODE、NAME、DWCODE、UNIT、BCFLAG、STDFLAG、DWFLAG、SZ、ZSSL_SET、CLDE、CJDL、TSL、SPLB、TSFLAG、NOTE。 ## 03、数据截图

    风机变桨控制FAST与MATLAB SIMULINK联合仿真模型:非线性风力发电机的PID独立与统一变桨控制策略对比研究,风机变桨控制FAST与MATLAB联合仿真研究:非线性风力发电机的PID独立与

    风机变桨控制FAST与MATLAB SIMULINK联合仿真模型:非线性风力发电机的PID独立与统一变桨控制策略对比研究,风机变桨控制FAST与MATLAB联合仿真研究:非线性风力发电机的PID独立与统一变桨控制在Trubsim 3D湍流风环境下的对比分析,风机变桨控制FAST与MATLAB SIMULINK联合仿真模型非线性风力发电机的 PID独立变桨和统一变桨控制下仿真模型,对于5WM非线性风机风机进行控制 链接simulink的scope出转速对比,桨距角对比,叶片挥舞力矩,轮毂处偏航力矩,俯仰力矩等载荷数据对比图,在trubsim生成的3D湍流风环境下模拟 统一变桨反馈信号是转速,独立变桨反馈是叶根载荷 提供包含openfast与matlab simulink联合仿真的建模 可以提供参考文献+模型+大佬交流群 ,核心关键词:FAST; MATLAB SIMULINK; 联合仿真模型; 非线性风力发电机; PID控制; 独立变桨; 统一变桨; 转速对比; 桨距角对比; 叶片挥舞力矩; 轮毂偏航力矩; 俯仰力矩; 3D湍流风环境; 建模; 参考文献; 模型交流群。,基于OpenF

    基于Unity,SenseAR的手势识别demo.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款,质量优质,放心下载使用

    jdk-8u441-windows-x64.zip

    java8版本的压缩包(windows)

    NMPC非线性模型预测控制:从原理到代码实践的全面解析,包含四项案例研究:自动泊车轨迹优化、倒立摆上翻控制、车辆运动学轨迹跟踪及四旋翼无人机轨迹跟踪,非线性模型预测控制在四个案例中的实践与应用:从原理

    NMPC非线性模型预测控制:从原理到代码实践的全面解析,包含四项案例研究:自动泊车轨迹优化、倒立摆上翻控制、车辆运动学轨迹跟踪及四旋翼无人机轨迹跟踪,非线性模型预测控制在四个案例中的实践与应用:从原理到代码实操指南,nmpc非线性模型预测控制从原理到代码实践 包含4个案例 1 自动泊车轨迹优化 2 倒立摆上翻控制 3 车辆运动学轨迹跟踪 4 四旋翼无人机轨迹跟踪 ,nmpc;非线性模型预测控制;原理;代码实践;案例;自动泊车轨迹优化;倒立摆上翻控制;车辆运动学轨迹跟踪;四旋翼无人机轨迹跟踪,NMPC非线性模型预测控制:原理与代码实践,四案例详解(含自动泊车、倒立摆、车辆轨迹跟踪及四旋翼无人机控制)

    Delphi 12 控件之Gnostice PDFToolkit v.5.0.0.860 for Delphi 11.7z

    Gnostice PDFToolkit v.5.0.0.860 for Delphi 11.7z

    CAD-Reader(cad快速看图)

    快速打开图纸:具有闪电般的启动速度,能快速打开各种版本的 DWG 图纸,让用户迅速开始查看和使用图纸。 显示完整准确:全面完整地显示布局、图案填充等内容,可自动匹配所有字体,有效解决中文乱码问题,能完美显示钢筋符号。 支持天正系列:是业内支持天正建筑、天正给排水、天正暖通、天正电气的 CAD 看图产品,方便建筑、给排水等相关专业人员查看和使用天正图纸。 便捷传图功能:内置 WiFi 直连电脑、云盘功能,方便用户在不同设备之间轻松传图,实现图纸的快速传输和共享。 多种操作功能:可添加各种注释,如线条、文字、图片等,还能精确扣点,方便用户对图纸进行标记和说明;具有所见即所得的打印方式,可自由设置打印范围;支持全屏看图,让用户获得更好的查看体验。 测量统计功能:能准确测量长度、半径、角度、弧长、坐标、多边形面积等,还可自动统计测量的长度和面积,可按颜色统计或手动统计,结果能导出表格。 高效协作功能:支持团队协同,用户可以在移动中处理工作,与合作伙伴随时沟通;可以捕获现场照片和录制语音消息并作为注释附加到图纸上,还能导入 / 导出图纸注释。

    单向手性光学腔的研究与应用 - Comsol的光学物理分析与实现,“Comsol模拟下的单向手性光学腔特性探究”,Comsol单向手性光学腔 ,核心关键词:Comsol; 单向手性; 光学腔; 模拟

    单向手性光学腔的研究与应用 - Comsol的光学物理分析与实现,“Comsol模拟下的单向手性光学腔特性探究”,Comsol单向手性光学腔。 ,核心关键词:Comsol; 单向手性; 光学腔; 模拟。,单向手性光学腔的Comsol模拟研究

    CDlinux镜像文件.zip

    目录: CDlinux_CE-0.9.5 CDlinux_CE-0.9.6.1 CDlinux_CE-0.9.7.1 CDlinux_mini-0.9.5 CDlinux_mini-0.9.6.1 CDlinux_mini-0.9.7.1 CDlinux-0.9.5.1 CDlinux-0.9.6.1 CDlinux-0.9.6 CDlinux-0.9.7.1 CDlinux-0.9.7 ........... 网盘文件永久链接

    基于maven的SSM整合 demo项目.zip(毕设&课设&实训&大作业&竞赛&项目)

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款,质量优质,放心下载使用

    MATLAB模态信号处理与小波阈值降噪的经典程序应用,Matlab小波阈值降噪与经典信号分解技术-模态降噪程序实践,matlab 小波阈值降噪,经典信号分解及降噪程序,模态 ,matlab;小波

    MATLAB模态信号处理与小波阈值降噪的经典程序应用,Matlab小波阈值降噪与经典信号分解技术——模态降噪程序实践,matlab 小波阈值降噪,经典信号分解及降噪程序,模态 ,matlab;小波阈值降噪;经典信号分解;模态降噪程序,MATLAB小波阈值降噪:经典信号分解与模态降噪程序

    “植屋”-网站设计 “植物”主题的网站,旨在科普一些植物培养、选种、购买的小知识 (html、css和js制作的静态网站).zip

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款,质量优质,放心下载使用

    基于MATLAB的虚拟电厂与微网双重不确定性随机优化调度模型研究与应用,基于随机优化算法的虚拟电厂与微网双重不确定性下的日前调度模型研究,MATLAB代码:计及源-荷双重不确定性的电厂 微网日前随机优

    基于MATLAB的虚拟电厂与微网双重不确定性随机优化调度模型研究与应用,基于随机优化算法的虚拟电厂与微网双重不确定性下的日前调度模型研究,MATLAB代码:计及源-荷双重不确定性的电厂 微网日前随机优化调度 关键词:电厂 微网 随机优化 随机调度 源-荷双重不确定性 电厂调度 参考文档:《Virtual power plant mid-term dispatch optimization》参考其燃气轮机、以及储能部分模型,另外随机优化算法也是和该文档一致; 仿真平台:MATLAB+CPLEX 主要内容:代码主要做的是一个电厂或者微网单元的日前优化调度模型,考虑了光伏出力和负荷功率的双重不确定性,采用随机规划法处理不确定性变量,构建了电厂随机优化调度模型。 具体来看,首先是基于蒙特卡洛算法,对预测的光伏以及负荷曲线进行场景生成,然后基于快概率距离快速消除法进行削减,直至削减至5个场景,然后采用随机调度的方法,对多场景下的电厂调度策略进行优化,程序实现效果良好,纯程序为本人亲自所写,一行一注释 ,关键词:虚拟电厂; 微网; 随机优化; 随机调度; 源-荷双重不确定性; 蒙特卡洛算法

Global site tag (gtag.js) - Google Analytics