【一个用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. 2019年华南理工大学程序设计竞赛(春季赛) B 修仙时在做什么?有没有空?可以来炼丹吗?(思维建图搜索)

    https://ac.nowcoder.com/acm/contest/625/B 分析: 全部的状态只有1<<18 个 , 所以我们可以预处理 f[u][j] , 然后建立出全部的u可以 ...

  2. 2019年华南理工大学程序设计竞赛(春季赛) K Parco_Love_String(后缀自动机)找两个串的相同字串有多少

    https://ac.nowcoder.com/acm/contest/625/K 题意: 给出Q 个询问 i , 求 s[0..i-1] 与 s[i...len-1] 有多少相同的字串 分析: 给出 ...

  3. 123th LeetCode Weekly Contest Broken Calculator

    On a broken calculator that has a number showing on its display, we can perform two operations: Doub ...

  4. 分分钟钟学会Python - 数据类型(set)

    目录 今日内容 具体内容 1.集合含义 2.独有方法 3.公共方法 4.特殊情况 5.总结 @ 今日内容 集合(set) 具体内容 1.集合含义 一个无序的不重复元素序列. 可以使用大括号 { } 或 ...

  5. reset.css(重置浏览器默认样式)

    @charset "utf-8";html{background-color:#fff;color:#000;font-size:12px} body,ul,ol,dl,dd,h1 ...

  6. 本科生毕业论文->计算机类(1)

    写在前面:作为一个计算机类学生,本文只是面向计算机类本科论文进行了一些小经验总结,每个学校的论文要求不一致,具体的参考规范可以看学校的通知,毕业论文作为毕业的一个重要审核标准,写好毕业论文是非常重要的 ...

  7. 浅谈flex布局

    Flex布局,俗称弹性布局,有了这个布局,咱们做的事情很多,以前那些很难实现比如说垂直居中之类都不存在了. 盒模型布局依赖于float,display,定位之类的方式来布局,这种的布局对一些特殊布局来 ...

  8. Win7与Ubuntu双系统安装过程

    Win7安装1.宏基安装Win7插入Win7系统光盘-> 重新启动-> 按F12-> 选择CD安装-> 按任意键-> 选择自定义(高级),接下去根据提示安装. 2.华硕安 ...

  9. 学习Python要知道哪些重要的库和工具

    本文转自:https://github.com/jobbole/awesome-python-cn 环境管理 管理 Python 版本和环境的工具 p:非常简单的交互式 python 版本管理工具. ...

  10. WAMP环境配置-Apache服务器的安装

    一.下载 下载地址:http://httpd.apache.org/ 在这里就可以下载想下载的版本了 二.安装 我这次环境配置安装的是Apache-2.4.23版本! (最近我在反复安装PHP的时候出 ...