【一个用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. MyEclipse配置,每次打开server中都没有weblogic

    最近在myeclipse新配了个weblogic,结果每次打开myeclipse在server中都看不到weblogic,得重新去配置页面走一遭才能出现.很麻烦. 后来在网上找了找,找到一个办法: 在 ...

  2. Leo-io 的C语言实现简单五子棋游戏观后感

    源代码: /************************************************************** ** 文 件 名:wuziqi.cpp ** 功    能:扫 ...

  3. IO概念解析------同步异步阻塞非阻塞

    各个IO Model的比较如图所示: 阻塞和非阻塞强调的是程序在等待调用结果(消息,返回值)时的状态.  阻塞调用是指调用结果返回之前,当前线程会被挂起.调用线程只有在得到结果之后才会返回.非阻塞调用 ...

  4. 《大数据日知录》读书笔记-ch16机器学习:分布式算法

    计算广告:逻辑回归 千次展示收益eCPM(Effective Cost Per Mille) eCPM= CTR * BidPrice 优化算法 训练数据使用:在线学习(online learning ...

  5. 使用WinSCP进行简单代码文件同步

    前言传输协议FTPFTPSSFTPSCP为什么使用WinSCP?CMD的FTP命令FileZillaPuTTYrsyncSublime的SFTP插件WinSCPWinSCP进行简单代码文件同步总结备注 ...

  6. RHCE 入门 第一篇

    随着工作压力越来越大,我们越需要技术储备. 从2017年10月14日开始参加RHCE培训

  7. 【LESS系列】简介和使用

    LESS —— 一个CSS预编译框架,它在CSS的语法基础之上,引入了变量.Mixin(混入).运算以及函数等功能,大大简化了CSS的编写,并且降低了CSS的维护成本,就像它的名称所说的那样,LESS ...

  8. poj 2954 Triangle

    pick公式+gcd公式 #include<iostream> #include<map> #include<string> #include<cstring ...

  9. Bash编程(6) String操作

    1. 拼接 1) 简单的字符串拼接如:PATH=$PATH:$HOME/bin.如果拼接的字符串包含空格或特殊字符,需要使用双引号括起,如: var=$HOME/bin # 注释并不是赋值的一部分 v ...

  10. 在create-react-app创建的React项目应用中配置JQ、Sass

    使用 create-react-app 配置 react 开发环境,像下面这样,就可以构建一个新的 react 单页面应用,非常方便. npm install -g create-react-app ...