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;
这是一个装饰器模式