【一个用NIO实现的客户端向服务端单向通信的例子】

【服务端程序】

package com.nio.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.util.Iterator; /**
* Created by cuixinjie on 2018/5/30.
*/
public class Server implements Runnable{ //1.多路复用器(管理所有的Channel)
private Selector selector;
//2.建立缓冲区
private ByteBuffer readBuffer = ByteBuffer.allocate(1024); public Server(int port){
try {
//1.打开多路复用器
this.selector = Selector.open();
//2.打开服务端通道Channel
ServerSocketChannel ssc = ServerSocketChannel.open();
//3.设置服务器通道为非阻塞模式
ssc.configureBlocking(false);
//4.绑定地址
ssc.bind(new InetSocketAddress(port));
//5.把服务器通道ssc注册到多路复用器selector上,并且监听阻塞事件
ssc.register(this.selector, SelectionKey.OP_ACCEPT); System.out.println("服务端已启动,监听port:"+port);
}catch (IOException e){
e.printStackTrace();
}
} @Override
public void run() {
while (true){
try{
//1.让多路复用器开始监听
this.selector.select();
//2.返回多路复用器已经选择的Key结果集
Iterator<SelectionKey> keys = this.selector.selectedKeys().iterator();
//3.进行遍历
while (keys.hasNext()){
//4.获取一个选择的的元素
SelectionKey key = keys.next();
//5.直接从容器中移除
keys.remove();
//6.如果是有效的
if(key.isValid()){
//7.如果是阻塞状态
if(key.isAcceptable()){
this.accept(key);
}
//8.如果是可读状态
if(key.isReadable()){
this.read(key);
}
}
}
}catch (IOException e){
e.printStackTrace();
}
}
} private void accept(SelectionKey key){
try{
//1.获取服务端通道
ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
//2.执行阻塞方法
SocketChannel sc = ssc.accept(); //注意:这里会一直阻塞到客户端的请求过来!
//3.设置阻塞模式
sc.configureBlocking(false);
//4.注册到多路复用器上,并设置读取标识
sc.register(this.selector,SelectionKey.OP_READ); }catch (IOException e){
e.printStackTrace();
}
} private void read(SelectionKey key ){
try{
//1.清空缓冲区旧的数据
this.readBuffer.clear();
//2.获取之前注册的Socket通道对象
SocketChannel sc = (SocketChannel)key.channel();
//3.读取数据
int count = sc.read(this.readBuffer);
//4.如果没有数据
if(count== -1){
key.channel().close();
key.cancel();
return;
}
//5.有数据则进行数据读取,读取之前需要进行复位方法(把position 和 limit进行复位)
this.readBuffer.flip();
//6.根据缓冲区的数据长度创建相应大小的byte数组,接收缓冲区的数据
byte[] bytes = new byte[this.readBuffer.remaining()];
//7.接收缓冲区数据
this.readBuffer.get(bytes);
//8.打印结果
String body = new String(bytes).trim();
System.out.println("服务端收到客户端的内容为:"+body);
}catch (IOException e){
e.printStackTrace();
}
} public static void main(String[] args) {
new Thread(new Server(8765)).start();
}
}

【客户端程序】

package com.nio.test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; /**
* Created by cuixinjie on 2018/5/30.
*/
public class Client { public static void main(String[] args) {
//创建连接的地址
InetSocketAddress address = new InetSocketAddress("127.0.0.1",8765); //声明连接通道
SocketChannel sc = null; //建立缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024); try{
//打开通道
sc = SocketChannel.open();
//进行连接
sc.connect(address);
while(true){
//定义一个字节数组,然后使用系统录入功能
byte[] bytes = new byte[1024];
System.out.print("客户端发送的数据为:");
System.in.read(bytes); //把数据的数据放入缓冲区中
buf.put(bytes);
//对缓冲区进行复位
buf.flip();
//写出数据
sc.write(buf);
//清空缓冲区数据
buf.clear();
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(null!=sc){
try{
sc.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}

【运行结果】

1.先启动服务端

2.再启动客户端,并输入需要传输的数据

3.再查看服务端接受的数据

02_NIO简单实例的更多相关文章

  1. Hibernate(二)__简单实例入门

    首先我们进一步理解什么是对象关系映射模型? 它将对数据库中数据的处理转化为对对象的处理.如下图所示: 入门简单实例: hiberante 可以用在 j2se 项目,也可以用在 j2ee (web项目中 ...

  2. 最新 Eclipse IDE下的Spring框架配置及简单实例

    前段时间开始着手学习Spring框架,又是买书又是看视频找教程的,可是鲜有介绍如何配置Spring+Eclipse的方法,现在将我的成功经验分享给大家. 本文的一些源代码来源于码农教程:http:// ...

  3. 修改js confirm alert 提示框文字的简单实例

    修改js confirm alert 提示框文字的简单实例: <!DOCTYPE html> <html> <head lang="en"> & ...

  4. 利用navicat创建存储过程、触发器和使用游标的简单实例

    利用navicat创建存储过程.触发器和使用游标的简单实例 标签: navicat存储过程触发器mysql游标 2013-08-03 21:34 15516人阅读 评论(1) 收藏 举报  分类: 数 ...

  5. 【转】Android Https服务器端和客户端简单实例

    转载地址:http://blog.csdn.net/gf771115/article/details/7827233 AndroidHttps服务器端和客户端简单实例 工具介绍 Eclipse3.7 ...

  6. Centos7的安装、Docker1.12.3的安装,以及Docker Swarm集群的简单实例

    目录 [TOC] 1.环境准备 ​ 本文中的案例会有四台机器,他们的Host和IP地址如下 c1 -> 10.0.0.31 c2 -> 10.0.0.32 c3 -> 10.0.0. ...

  7. vue路由的简单实例

    vue2.0 和 vue1.0 路由的语法还是有点稍微的差别,下面介绍一下vue-router 2的简单实例: <!DOCTYPE html> <html lang="en ...

  8. Flume概述和简单实例

    Flume概述 Flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统.支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方( ...

  9. jsoup解析HTML及简单实例

    jsoup 中文参考文献    http://www.open-open.com/jsoup/ 本文将利用jsoup,简单实现网络抓取的功能,并给出一个小实例,该实例效果为:获取作者本人在博客园写的所 ...

随机推荐

  1. 微信小程序通过background-image设置背景图片

    微信小程序通过background-image设置背景:只支持线上图片和base64图片,不支持本地图片:base64图片设置步骤如下:1.在网站http://imgbase64.duoshitong ...

  2. css实现渐变

    .gradient{ background: -webkit-gradient(linear, 0 0, 0 100%, from(#8ca0d3), to(#375a9a)); /** Chrome ...

  3. linux 系统管理(2) 文件或目录数量统计

    统计某文件夹下文件的个数 ls -l |grep "^-"|wc -l 统计某文件夹下目录的个数 ls -l |grep "^d"|wc -l 统计文件夹下文件 ...

  4. 论文阅读 | FPN:Feature Pyramid Networks for Object Detection

    论文地址:https://arxiv.org/pdf/1612.03144v2.pdf 代码地址:https://github.com/unsky/FPN 概述 FPN是FAIR发表在CVPR 201 ...

  5. 固定定位 z-index iconfont的使用 043

    固定定位  现象 脱标 提升层级  将盒子固定住 参考点 浏览器的左上角 : <!DOCTYPE html> <html lang="en"> <he ...

  6. JSON 请求太大,无法反序列化。

    在post请求中数据太大导致报500错误.错误提示 JSON 请求太大,无法反序列化. 在config中加 <system.web.extensions> <scripting> ...

  7. 详解exif.js,应用于canvas照片倒转(海报H5)

    业务背景,苹果手机调用上传接口拍照没有问题但是上传到网页上照片倒转了解决方法利用exif.js读取图片参数并对图片进行元数据修改 window.btoa(str)转码 window.atob(base ...

  8. 《大数据日知录》读书笔记-ch3大数据常用的算法与数据结构

    布隆过滤器(bloom filter,BF): 二进制向量数据结构,时空效率很好,尤其是空间效率极高.作用:检测某个元素在某个巨量集合中存在. 构造: 查询: 不会发生漏判(false negativ ...

  9. ionic3 cordova 调取软键盘

    应用场景,因为兼容ios,安卓问题,不能直接调用激活软键盘方法.只有在点击按钮时让input框自动获取焦点,激活软键盘.然后把input框定位在键盘上方,软键盘激活可以监听到键盘高度. 先下载keyb ...

  10. 设置开机自动运行vncserver

    a. 在/etc/rc.d/rc.local文件中加入下面行   /etc/init.d/vncserver startb. 编辑/etc/sysconfig/vncservers   VNCSERV ...