JAVA-7NIO之Socket/ServerSocket Channel

1、ServerSocketChannel

Java NIO中的 ServerSocketChannel 是一个能够监听新进来的TCP链接的通道, 就像标准IO中的ServerSocket同样。ServerSocketChannel类在 java.nio.channels包中。java

打开 ServerSocketChannel

经过调用 ServerSocketChannel.open() 方法来打开ServerSocketChannel.服务器

关闭 ServerSocketChannel

经过调用ServerSocketChannel.close() 方法来关闭ServerSocketChannel. 网络

监听新进来的链接

经过 ServerSocketChannel.accept() 方法监听新进来的链接。当 accept()方法返回的时候,它返回一个包含新进来的链接的 SocketChannel。所以, accept()方法会一直阻塞到有新链接到达。异步

一般不会仅仅只监听一个链接,在while循环中调用 accept()方法. socket

固然,也能够在while循环中使用除了true之外的其它退出准则。spa

非阻塞模式

ServerSocketChannel能够设置成非阻塞模式。在非阻塞模式下,accept() 方法会马上返回,若是尚未新进来的链接,返回的将是null。 所以,须要检查返回的SocketChannel是不是null.如:code

    /**
     * socket server channel
     */
    @Test
    public void text2() throws IOException {
        ServerSocketChannel channel = ServerSocketChannel.open();    //新建channel
        channel.socket().bind(new InetSocketAddress(9999));     //监听端口
        channel.configureBlocking(true);                             //设置阻塞

        while (true) {
            SocketChannel accept = channel.accept();                    //设置为阻塞,则此方法阻塞,直到有链接
            //若是设置为非阻塞,须要在这里判断 accept == null?
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            accept.read(byteBuffer);
            byteBuffer.flip();                                    //反转
            while (byteBuffer.hasRemaining()) {                   //判断
                System.err.println((char)byteBuffer.get());       //输出
            }
        }
    }

 

2、SocketChannel

Java NIO中的SocketChannel是一个链接到TCP网络套接字的通道。能够经过如下2种方式建立SocketChannel:server

  1. 打开一个SocketChannel并链接到互联网上的某台服务器。
  2. 一个新链接到达ServerSocketChannel时,会建立一个SocketChannel。

打开 SocketChannel

下面是SocketChannel的打开方式:blog

关闭 SocketChannel

当用完SocketChannel以后调用SocketChannel.close()关闭SocketChannel:ip

从 SocketChannel 读取数据

要从SocketChannel中读取数据,调用一个read()的方法之一。

首先,分配一个Buffer。从SocketChannel读取到的数据将会放到这个Buffer中。

而后,调用SocketChannel.read()。该方法将数据从SocketChannel 读到Buffer中。read()方法返回的int值表示读了多少字节进Buffer里。若是返回的是-1,表示已经读到了流的末尾(链接关闭了)。

写入 SocketChannel

写数据到SocketChannel用的是SocketChannel.write()方法,该方法以一个Buffer做为参数。

注意SocketChannel.write()方法的调用是在一个while循环中的。Write()方法没法保证能写多少字节到SocketChannel。因此,咱们重复调用write()直到Buffer没有要写的字节为止。

非阻塞模式

能够设置 SocketChannel 为非阻塞模式(non-blocking mode).设置以后,就能够在异步模式下调用connect(), read() 和write()了。

connect()

若是SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在链接创建以前就返回了。为了肯定链接是否创建,能够调用finishConnect()的方法。

 

write()

非阻塞模式下,write()方法在还没有写出任何内容时可能就返回了。因此须要在循环中调用write()。前面已经有例子了,这里就不赘述了。

read()

非阻塞模式下,read()方法在还没有读取到任何数据时可能就返回了。因此须要关注它的int返回值,它会告诉你读取了多少字节。

非阻塞模式与选择器

非阻塞模式与选择器搭配会工做的更好,经过将一或多个SocketChannel注册到Selector,能够询问选择器哪一个通道已经准备好了读取,写入等。Selector与SocketChannel的搭配使用会在后面详讲。

/**
     * socket channel
     */
    @Test
    public void test3() throws IOException {
        SocketChannel channel = SocketChannel.open();                               //新建服务端
        channel.connect(new InetSocketAddress("127.0.0.1",9999));   //链接服务端地址
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);  //缓冲区
        byteBuffer.put("123".getBytes());
        byteBuffer.flip();                                  //反转
        while (byteBuffer.hasRemaining()) {                 //判断
            channel.write(byteBuffer);
        }
    }
相关文章
相关标签/搜索