今天先介绍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();

}

}

}

}

161111、NioSocket的用法(new IO)的更多相关文章

  1. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  2. 第一篇 网站基础知识 第4章 Java中Socket的用法

    第4章 Java中Socket的用法 4.1 普通Socket的用法 Java中的网络通信是通过Socket实现的,Socket分为ServetSocket和Socket两大类,ServetSocke ...

  3. Java中的Socket用法

    转发链接:https://www.cnblogs.com/zhanglei93/p/6217384.html (1)Java中的Socket用法 Java中的Socket分为普通的Socket和Nio ...

  4. 利用socket.io实现消息实时推送

    最近在写的项目中存在着社交模块,需要实现这样的一个功能:当发生了用户被点赞.评论.关注等操作时,需要由服务器向用户实时地推送一条消息.最终完成的项目地址为:socket-message-push,这里 ...

  5. 高级Java工程师必备 ----- 深入分析 Java IO (三)

    概述 Java IO即Java 输入输出系统.不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒介进行IO( ...

  6. Java之io nio aio 的区别

    这个问题最近面试总是遇到,作为一个只会写流水代码的程序员,一脸懵逼.看了网上的解释,看的还是很模糊,说下我对这个的理解. 先引出一个话题,两个大水缸,一个空一个满,让你把一个缸里面的水弄到另一个里面. ...

  7. 转: 从Mysql某一表中随机读取n条数据的SQL查询语句

    若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)).例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机 ...

  8. .net(C#)操作文件的几种方法汇总

    .net(C#)操作文件的几种方法汇总 System.IO命名空间下类的用法:在System.IO名称空间中包含了用于文件输入输出的主要类.File:实用类,提供许多静态方法,用于移动.复制和删除文件 ...

  9. 【MySQL性能优化】改进MySQL Order By Rand()的低效率

    <a href="http://click.aliyun.com/m/9153/">点击查看原文</a> 正 文:   最近由于需要研究了一下MYSQL的随 ...

随机推荐

  1. ant简述

    1,什么是antant是构建工具2,什么是构建概念到处可查到,形象来说,你要把代码从某个地方拿来,编译,再拷贝到某个地方去等等操作,当然不仅与此,但是主要用来干这个3,ant的好处跨平台   --因为 ...

  2. thinkphp添加后台的构思以及添加数据功能

    先写个表单提交,这就是个简单的后台了...其实也可以通过phpadmin...phpadmin也叫后台的吧...一切都是为了更方便快捷... 先弄个模板,简单了点,就是为了了解实现的流程和原理 < ...

  3. axis2 WebService的发布与调用

    1:准备:    JDK:http://www.oracle.com/technetwork/java/javase/downloads/jdk6downloads-1902814.html    e ...

  4. Power-BI仪表盘文本框排行分析设计要点

    例如:我在BI软件中做一个商品类别TOP5排行. 文本框默认绑定第一列,但是没显示是那个品类. 这里我们需要做几个操作来进行优化. 1.把品类显示出来. 在序列中找到标题进行显示,如果位置有重叠可以进 ...

  5. Android中读取短信信息

    Android中读取的短信文件有 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /**  * 所有的短信  */ public static final Strin ...

  6. BCP及自增标识列

    10:58 2012-12-20 通过BCP命令导入导出数据 bcp "test.dbo.lxy133" out d:\lxy133.txt -SMSSQL$SQL08R2 -Us ...

  7. javascript实例学习之五——瀑布流布局

    瀑布流布局的特征: 1,各列的高度参差不齐 2,页面向下滚动时,自动请求和加载新数据 目前,瀑布流布局的主流实现方式有两种: 1,基于浮动,每一列是一个ul,这些ul都向左浮动,这种方法的好处是布局容 ...

  8. C# 集合-并发处理-锁OR线程

    每次写博客,第一句话都是这样的:程序员很苦逼,除了会写程序,还得会写博客!当然,希望将来的一天,某位老板看到此博客,给你的程序员职工加点薪资吧!因为程序员的世界除了苦逼就是沉默.我眼中的程序员大多都不 ...

  9. PostgreSQL中美元符号引用的字符串常量

    虽然用于指定字符串常量的标准语法通常都很方便,但是当字符串中包含了很多单引号或反斜线时很难理解它,因为每一个都需要被双写.要在这种情形下允许可读性更好的查询,PostgreSQL提供了另一种被称为“美 ...

  10. Leetcode: Alien Dictionary && Summary: Topological Sort

    There is a new alien language which uses the latin alphabet. However, the order among letters are un ...