【一个用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. JQuery.Validate学习笔记

    JQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 URL 和电子邮件验证 ...

  2. print高亮显示

    显示颜色格式:\033[显示方式;字体色;背景色m......[\033[0m] ------------------------------------------- --------------- ...

  3. php7 中?? 和 ?:的区别

    $b = $a?? $c ;相当于$b= isset($a)?$a:$c; $b = $a?: $c ;则是 $b = !empty($a) ? $a:$c;

  4. nginx实现多语言跳转不同的url

    nginx实现多语言跳转不同的url server { listen 80; server_name www.text.com; location / { if ($http_accept_langu ...

  5. D3.js绘制平行坐标图

    参照:https://syntagmatic.github.io/parallel-coordinates/ 和 https://github.com/syntagmatic/parallel-coo ...

  6. C# GridView 导出Excel表

    出错1:类型“GridView”的控件“GridView1”必须放在具有 runat=server 的窗体标记内解决方案:在后台文件中重载VerifyRenderingInServerForm方法,如 ...

  7. 为什么要实现Serializable

    工作中我们经常在进行持久化操作和返回数据时都会使用到javabean来统一封装参数,方便操作,一般我们也都会实现Serializable接口,那么问题来了,首先:为什么要进行序列化:其次:每个实体be ...

  8. android httpclient 发送 PATCH 请求

    Put 用于全部更新 Patch 用于部分更新 重写一下 HttpPut 或 HttpPost 的 getMethod 方法 /** * Send a patch request */ public ...

  9. 【随笔】 MyEclipse2014的安装和破解

    MyEclipse,是在eclipse 基础上加上了自己的插件.MyEclipse,是在eclipse 基础上加上自己的插件开发而成的功能强大的企业级集成开发环境,主要用于Java.Java EE以及 ...

  10. 【随笔】设置title标题图标为自定义图片

    第一步: 利用图标工具(有很多)制作图标文件(favicon.ico)上传到网站所在的服务器的根目录下,这个文件必须是16*16大小的图标文件. 第二步: 在<head></head ...