NIO编程
来源:互联网 发布:淘宝号出租平台 编辑:程序博客网 时间:2024/05/17 06:24
public class Server implements Runnable{
//1多路复用器(管理所有同道)
private Selector selector;
//2建立缓冲区
private ByteBuffer readBuf = ByteBuffer.allocate(1024);
//3
private ByteBuffer writeBuf = ByteBuffer.allocate(1024);
public Server(int port){
try{
//1打开路复用器
this.selector = Selector.open();
//2打服务器道
ServerSocketChannel ssc = ServerSocketChannel.open();
//3设置复用器通道为非阻塞模式
ssc.configureBlocking(false);
//4绑定地址
ssc.bind(new InetSocketAddress(port));
//5把服务器通道注册到多路复用器上,并监听阻塞事件
ssc.register(this.selector, SelectionKey.OP_ACCEPT);
System.out.println("Server start,port:"+port);
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
try{
//1 必须让多路复用器开始监听
this.selector.select();
//2返回多路复用器已选择的结果集
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);
}
//写数据
if(key.isWritable()){
this.write(key);
}
}
}
}catch(IOException e){
e.printStackTrace();
}
}
}
public void read(SelectionKey key){
try{
//1清空缓冲区旧的数据
this.readBuf.clear();
//2获取之前注册的socket通道对象
SocketChannel sc = (SocketChannel) key.channel();
//3读取数据
int count = sc.read(this.readBuf);
//4如果没有数据
if(count == -1){
key.channel().close();
key.cancel();return;
}
//5有数据进行读取 读取之前需要进行复位方法(把posion和limit进行复位)
this.readBuf.flip();
//6根据缓冲区的数据长度创建相应大小的byte数组,接收缓冲区的数据
byte[] bytes = new byte[this.readBuf.remaining()];
//7接受缓冲区数据
this.readBuf.get(bytes);
//8打印结果
String body = new String(bytes).trim();
System.out.println("Server : " + body);
//9可以写回给客户端数据
}catch(Exception e){
e.printStackTrace();
}
}
public void write(SelectionKey key){
//ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
//ssc.register(this.seletor, SelectionKey.OP_WRITE);
}
public 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();
}
}
public static void main(String[] args) {
new Thread(new Server(8765)).start();
}
//1多路复用器(管理所有同道)
private Selector selector;
//2建立缓冲区
private ByteBuffer readBuf = ByteBuffer.allocate(1024);
//3
private ByteBuffer writeBuf = ByteBuffer.allocate(1024);
public Server(int port){
try{
//1打开路复用器
this.selector = Selector.open();
//2打服务器道
ServerSocketChannel ssc = ServerSocketChannel.open();
//3设置复用器通道为非阻塞模式
ssc.configureBlocking(false);
//4绑定地址
ssc.bind(new InetSocketAddress(port));
//5把服务器通道注册到多路复用器上,并监听阻塞事件
ssc.register(this.selector, SelectionKey.OP_ACCEPT);
System.out.println("Server start,port:"+port);
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
try{
//1 必须让多路复用器开始监听
this.selector.select();
//2返回多路复用器已选择的结果集
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);
}
//写数据
if(key.isWritable()){
this.write(key);
}
}
}
}catch(IOException e){
e.printStackTrace();
}
}
}
public void read(SelectionKey key){
try{
//1清空缓冲区旧的数据
this.readBuf.clear();
//2获取之前注册的socket通道对象
SocketChannel sc = (SocketChannel) key.channel();
//3读取数据
int count = sc.read(this.readBuf);
//4如果没有数据
if(count == -1){
key.channel().close();
key.cancel();return;
}
//5有数据进行读取 读取之前需要进行复位方法(把posion和limit进行复位)
this.readBuf.flip();
//6根据缓冲区的数据长度创建相应大小的byte数组,接收缓冲区的数据
byte[] bytes = new byte[this.readBuf.remaining()];
//7接受缓冲区数据
this.readBuf.get(bytes);
//8打印结果
String body = new String(bytes).trim();
System.out.println("Server : " + body);
//9可以写回给客户端数据
}catch(Exception e){
e.printStackTrace();
}
}
public void write(SelectionKey key){
//ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
//ssc.register(this.seletor, SelectionKey.OP_WRITE);
}
public 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();
}
}
public static void main(String[] args) {
new Thread(new Server(8765)).start();
}
}
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);//建立连接 注册到selector
while(true){
byte[] bytes = new byte[1024];
System.in.read(bytes);
buf.put(bytes);
buf.flip();
sc.write(buf);
buf.clear();
}
}catch(IOException e){
e.printStackTrace();
}finally{
if(sc != null){
try {
sc.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
阅读全文
0 0
- NIO编程
- NIO编程
- NIO编程
- NIO编程
- Java NIO TCP编程
- Java NIO编程关注点
- NIO的Socket编程
- java nio编程细节
- nio高并发编程
- Java 网络编程nio
- Java NIO 网络编程
- Java NIO编程
- Java高级编程-NIO
- nio高并发编程
- Java NIO 编程总结
- java NIO 网络编程
- NIO编程 TimeServer && TimeClient
- Java NIO网络编程
- Vue.js之深入浅出
- 关于IoC的 注入 与 装配
- 机器学习基石 7.1 Definition of VC Dimension
- tensorflow移植到手机端(TensorFlow Android Camera Demo)的实现
- 基于JavaMail的Java邮件发送(简单邮件发送)
- NIO编程
- Swift UIViewController中的delegate方式传值
- 文章网址记载
- JAVA总结(三):sun.jnu.encoding与file.encoding的区别
- 洛谷 入门综合练习2
- 权限管理设计
- 利用JScript实现简单的地址选择
- hdu 6105 Gameia(树形DP)
- React Native编辑器Atom+Nuclide插件的配置和安装及编译项目