网络编程复习(三):NIO模式
发布日期:2021-11-13 10:21:49 浏览次数:4 分类:技术文章

本文共 4165 字,大约阅读时间需要 13 分钟。

关于NIO,就是同步非阻塞,虽然效率会提高,但实现起来的有点麻烦,所以实际开发中用的很少,更多的是用Netty框架使用网络Socket,Netty其实是对JDK的nio的一个优化封装,实现起来更加方便,后续也将会介绍,下面看看流程图解:


client端:

package 网络编程_NIO;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;public class Client {
public static void main(String[] args) {
//定义socket连接的地址与端口
InetSocketAddress address = new InetSocketAddress("127.0.0.1",8888);
//通道
SocketChannel channel = null;
//缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
try {
//打开通道
channel = SocketChannel.open();
//连接地址
channel.connect(address);
while(true){
byte[] bys = new byte[1024];
//控制台读取数据1024字节
System.in.read(bys);
//数据放入缓冲区
buffer.put(bys);
//复位
buffer.flip();
//通道将缓冲区数据写给服务端
channel.write(buffer);
//清空缓冲区
buffer.clear();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(channel!=null){
try {
channel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}}

server端:

package 网络编程_NIO;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;public class Server implements Runnable{
private Selector selector;
private ByteBuffer readerBuffer = ByteBuffer.allocate(1024);
//private ByteBuffer writerBuffer = ByteBuffer.allocate(1024);
public  Server(int port) {
try {
//打开多路复用器
this.selector = Selector.open();
//打开连接通道
ServerSocketChannel socketChannel = ServerSocketChannel.open();
//设置为非阻塞模式
socketChannel.configureBlocking(false);
//通道绑定端口监听
socketChannel.bind(new InetSocketAddress(port));
//通道注册到多路复用器上
socketChannel.register(this.selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started..."+port);
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
public void run() {
while(true){
try {
//多路复用器开始监听
this.selector.select();
//返回多路复用器选择的结果集
Iterator  keys = this.selector.selectedKeys().iterator();
//开始遍历
while(keys.hasNext()){
//获得选择的第一个元素
SelectionKey key = keys.next();
//将选择的元素从容器中移除
keys.remove();
//如果元素可用
if(key.isValid()){
//如果为阻塞状态
if(key.isAcceptable()){
this.accept(key);
}
//可读
if(key.isReadable()){
this.read(key);
}
//可写
if(key.isWritable()){
this.writer(key);
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void writer(SelectionKey key) {
/*this.writerBuffer.clear();
SocketChannel channel  = (SocketChannel) key.channel();
byte[] bys = new String("服务端已经接受到你的数据").getBytes();
writerBuffer.put(bys);
writerBuffer.flip();
try {
channel.write(writerBuffer);
writerBuffer.clear();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
private void read(SelectionKey key) {
try {
this.readerBuffer.clear();
SocketChannel channel = (SocketChannel) key.channel();
int count = channel.read(readerBuffer);
if(count == -1){
key.channel().close();
key.cancel();
return;
}
this.readerBuffer.flip();
byte[] bys = new byte[this.readerBuffer.remaining()];
this.readerBuffer.get(bys);
String body = new String(bys).trim();
System.out.println("Server"+body);
//channel.register(this.selector, SelectionKey.OP_WRITE);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void accept(SelectionKey key) {
try {
ServerSocketChannel socketChannel = (ServerSocketChannel) key.channel();
SocketChannel channel = socketChannel.accept();
channel.configureBlocking(false);
//阻塞状态变为可读状态
channel.register(this.selector, SelectionKey.OP_READ);
} catch (Exception e) {
// TODO: handle exception
}
}
public static void main(String[] args) {
new Thread(new Server(8888)).start();
}}

这里我并没有实现服务端向客户端写数据,因为这种情况客户端也像一个服务端了,实现起来和server端代码很相似,加一个Selector就行了,这里感觉很麻烦,所以没有实现,有兴趣的朋友可以试下。

转载地址:https://blog.csdn.net/Lee_Ho_/article/details/78122588 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:网络编程复习(四):AIO
下一篇:网络编程复习(二):JDK1.5之前的伪异步BIO编程

发表评论

最新留言

关注你微信了!
[***.249.68.82]2022年04月17日 13时58分02秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

最新文章

android 5.0 miui7,小米官网公布MIUI7为啥不使用Android5.0 2019-08-20 03:55:30
android版本适配11,零时差适配安卓11!ColorOS 11升级公测版体验:丝滑顺畅 2019-08-20 03:55:29
win10部署android,atxserver2部署--基于Windows10系统(Android) 2019-08-20 03:55:29
android点击事件内容改变,android输入框内容改变的监听事件实例 2019-08-20 03:55:28
华为鸿蒙中标麒麟,华为鸿蒙OS短时间内威胁不到麒麟操作系统和统信UOS系统 2019-08-20 03:55:28
鸿蒙手机品牌,你好,鸿蒙!首个第三方接入鸿蒙品牌出现,华为再也不孤单了!... 2019-08-20 03:55:28
android ontouchevent 坐标,android处理触摸事件(touchEvent)的详细流程 2019-08-20 03:55:27
mips-mti-gnu-linux,c – 关于MIPS的pthreads中的Segfault 2019-08-20 03:55:27
c语言int mark,C语言考前冲刺题 2019-08-20 03:55:26
linux中cd 破折号,何时以及如何在Unix / Linux中引入双破折号(-)作为选项定界符的结尾?... 2019-08-20 03:55:26
c语言开题报告中的文件与格式,大学论文开题报告格式要求.docx 2019-08-20 03:55:25
C语言分乘积最大数,很大的数相乘怎么办? 2019-08-20 03:55:25
vs2019怎么编译c语言代码GIt,VS2019中Git源代码管理实现总结 2019-08-20 03:55:24
c语言程序实训报告模板,C语言实训报告模板..doc 2019-08-20 03:55:24
c语言程序断点怎么打,C#中如何使用断点操作调试程序 2019-08-20 03:55:23
c语言迷宫问题输出坐标,c语言栈解决迷宫问题 2019-08-20 03:55:23
asus t100ha linux,华硕变形本怎么样 | 华硕变形本T100HA 好不好_什么值得买 2019-08-20 03:55:23
c语言 预处理指令有什么作用,C语言程序时经常使用库函数之前的预处理是什么?... 2019-08-20 03:55:22
江苏大学linux实验报告,2019江苏大学885 编程题 2019-08-20 03:55:22
linux cron实例,cron,linux定时实施工具详解及实例 2019-08-20 03:55:21