socket():新建一个文件

bind():绑定到端口,第一个参数就是socket()方法产生的文件描述符

listen():确定新建的这个socket是一个服务器,被动等待网络其他进程链接,参数有个最大值:等待连接队列和成功连接队列之和的最大值

accept():如果绑定的端口上有新连接建立,那么为这个连接建立一个socket,或者说文件,返回一个描述符

为什么accept比select慢?accept是遍历连接,要阻塞等待每一个请求数据发送完,即socket文件可读

而select或者epoll直接读取可读的文件。 

channel是干啥的?

其实ServerSocket和socket是对SocketImpl这个实现类的封装,SocketImpl才是真正的描述文件的类。而前两者的作用是封装和标志状态

ServerSocketAdaptor继承了 java.net.ServerSocket,有ServerSocketChannelImpl的引用。ServerSocketChannel的socket()方法返回的就是ServerSocketAdaptor,继承了java.net.ServerSocket并重写bind方法。

在socketChannel中,调用的是getImpl().bind(epoint.getAddress(), epoint.getPort());
在ServerSocketAdaptor中,调用的是ssc.bind(local, backlog);,其中ssc是ServerSocketChannelImpl的引用。

上面说了,nio的ServerSocketAdaptor是对bio的ServerSocket的封装,nio的ServerSocketChannelImpl和bio的SocketImpl是差不多的东西,都是对文件的被描述。nio的channel是对selector的适配

而netty的nioserversocketchannel是对nio的channel的封装:具体表现在:

用bootstrap的initAndRegister方法,返回的ChannelFuture(或者说其实现接口ChannelPromise)是对channel的封装

public class DefaultChannelPromise  {

private final Channel channel;

}

,或者叫适配,因为实现了future接口,所以会对线程进行控制,调配等

而new出来的channel的构造方法是:

public NioServerSocketChannel() {
super(null, null, newSocket(), SelectionKey.OP_ACCEPT);
config = new DefaultServerSocketChannelConfig(this, javaChannel().socket());
}

先看其中的super

protected AbstractNioChannel(
Channel parent, Integer id, SelectableChannel ch, int readInterestOp) {
super(parent, id);
this.ch = ch;
this.readInterestOp = readInterestOp;

第三个参数是通过new socket()里面的方法是熟悉的nio的return ServerSocketChannel.open()---(new一个ssc)也就是说,ch这个属性里保存了nio的channelimpl;

这是一个装饰器模式