zoukankan      html  css  js  c++  java
  • 161111、NioSocket的用法(new IO)

    今天先介绍NioSocket的基本用法,实际使用一般会采用多线程,后面会介绍多线程的处理方法。

    从jdk1.4开始,java增加了新的io模式--nio(new IO),nio在底层采用了新的处理方式,极大地提高了IO效率。我们使用的Socket也属于IO的一种,nio提供了相应的工具:ServerSocketChanner和SocketChannel,它们分别对应ServerSocket和Socket。(不了解java socket可以百度下)

    NioSocket包括三个重要的概念:Buffer(类似于送快递中的货物)、Channel(类似于送快递中的送货车)和Selector(类似于送快递中转站的分拣员)。原来的Socket类似于一个人送快递,没有形成产业链。

    下面来看下代码:

    服务端

    package com.test;

    import java.io.IOException;

    import java.net.InetSocketAddress;

    import java.nio.ByteBuffer;

    import java.nio.channels.SelectionKey;

    import java.nio.channels.Selector;

    import java.nio.channels.ServerSocketChannel;

    import java.nio.channels.SocketChannel;

    import java.nio.charset.Charset;

    import java.util.Iterator;

    public class NIOServer {

    public static void main(String[] args) throws Exception {

    //创建ServerSocketChannel,监听8080端口

    ServerSocketChannel ssc =  ServerSocketChannel.open();

    ssc.socket().bind(new InetSocketAddress(8080));

    //设置为非阻塞模式

    ssc.configureBlocking(false);

    //为ServerSocketChannel注册选择器

    Selector selector = Selector.open();

    /**

    * 这里有四种SelectionKey分别表示接受请求操作、链接操作、读操作和写操作

    * SelectionKey.OP_ACCEPT

    * SelectionKey.OP_CONNECT

    * SelectionKey.OP_READ

    * SelectionKey.OP_WRITE

    */

    ssc.register(selector, SelectionKey.OP_ACCEPT);

    //创建处理器

    Handler handler = new Handler(1024);//handler的创建在下面静态的内部类中

    while(true){

    //等待请求,每次等待阻塞3s,超过3s后线程继续向下运动,如果传入0或者不传入参数将一直阻塞

    if(selector.select(3000) == 0){

    System.out.println("等待请求超时....");

    continue;

    }

    System.out.println("处理请求......");

    //获取待处理的SelectionKey

    Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();

    while(keyIter.hasNext()){

    SelectionKey key = keyIter.next();

    try {

    //接收到链接请求时

    if(key.isAcceptable()){

    handler.handAccept(key);//改变Selector为读操作

    }

    //读数据

    if(key.isReadable()){

    handler.handlerRead(key);

    }

    } catch (Exception e) {

    keyIter.remove();

    continue;

    }

    //处理完成后,从待处理的SelectionKey迭代器中移除当前所使用的key

    keyIter.remove();

    }

    }

    }

    public static class Handler{

    private int bufferSize = 1024;

    private String localCharset = "UTF-8";

    public Handler() {}

    public Handler(int bufferSize) {

    this(bufferSize,null);

    }

    public Handler(String localCharset) {

    this(-1,localCharset);

    }

    public Handler(int bufferSize, String localCharset) {

    if(bufferSize>0){

    this.bufferSize = bufferSize;

    }

    if(localCharset != null){

    this.localCharset = localCharset;

    }

    }

    public void handAccept(SelectionKey key) throws IOException {

    SocketChannel sc = ((ServerSocketChannel)key.channel()).accept();

    sc.configureBlocking(false);

    sc.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(bufferSize));//改变Selector为读操作

    }

    public void handlerRead(SelectionKey key) throws IOException {

    //获取channel

    SocketChannel sc = (SocketChannel) key.channel();

    //获取channel并重置

    ByteBuffer buffer = (ByteBuffer) key.attachment();

    buffer.clear();

    //没有读到内容则关闭

    if(sc.read(buffer)==-1){

    sc.close();

    }else{

    //将buffer转成读状态

    buffer.flip();

    //将buffer中接收到的值按localCharset格式编码后保存到receivedString

    String receivedString = Charset.forName(localCharset).newDecoder().decode(buffer).toString();

    System.out.println("received from client: " + receivedString);

    //返回数据给客户端

    String sendString = "received data: " + receivedString;

    buffer = ByteBuffer.wrap(sendString.getBytes(localCharset));

    sc.write(buffer);

    //关闭socket

    sc.close();

    }

    }

    }

    }

  • 相关阅读:
    Linux Shell 重定向输入和输出
    NDK Cmake
    测试
    20行Python代码爬取王者荣耀全英雄皮肤
    SSH开发模式——Struts2(第一小节)
    JavaWeb开发——软件国际化(动态元素国际化)
    JavaWeb开发——软件国际化(文本元素国际化)
    DBUtils框架的使用(下)
    DBUtils框架的使用(上)
    SSH开发模式——Struts2(第二小节)
  • 原文地址:https://www.cnblogs.com/zrbfree/p/6137326.html
Copyright © 2011-2022 走看看