JAVA -NIO实现(一)
来源:互联网 发布:unity3d 中国象棋 编辑:程序博客网 时间:2024/05/22 23:26
package com.liu.server;
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;
import java.util.Set;
/*
* 自定义服务器
*/
public class NIOServer {
private static int SERVER_PORT = 9000;
private static String SERVER_URI = "127.0.0.1";
private final static int BLOCK = 4096;
private static ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK);
private static ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK);
private ServerSocketChannel serverSocketChannel = null;
private Selector selector = null;
public static void main(String[] args) {
NIOServer server = new NIOServer();
server.start();
}
private void start(){
try {
this.initServer();
this.initService();
} catch (IOException e) {
e.printStackTrace();
}
}
private void initServer(){
try {
serverSocketChannel = ServerSocketChannel.open();
//静态方法 实例化selector
selector = Selector.open();
//设置为非阻塞方式,如果为true 那么就为传统的阻塞方式
serverSocketChannel.configureBlocking(false);
/*
* 通过这个选项,可以使多个Socket对象绑定在同一个端口上。其实这样做并没有多大意义,但当使用close方法关闭Socket连接后,
* Socket对象所绑定的端口并不一定马上释放;系统有时在Socket连接关闭才会再确认一下是否有因为延迟面未到达的数据包,
* 这完全是在底层处理的,也就是说对用户是透明的;因此,在使用Socket类时完全不会感觉到。
* 这种处理机制对于随机绑定端口的Socket对象没有什么影响,
* 但对于绑定在固定端口的Socket对象就可能会抛出“Address already in use: JVM_Bind”例外。
* 因此,使用这个选项可以避免个例外的发生。
*/
serverSocketChannel.socket().setReuseAddress(true);
//绑定端口
serverSocketChannel.socket().bind(new InetSocketAddress(SERVER_URI,SERVER_PORT));
/*
* 设置服务处于可接受信息的状态,即在服务中注册KEY,告诉服务 现在以经处于属于接受状态
*/
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("NIOServer is starting at " + SERVER_PORT + "......");
} catch (IOException e) {
e.printStackTrace();
}
}
private void initService() throws IOException{
while(selector.select()>0){
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectionKeys.iterator();
System.out.println("目前已经接受的key的 size : " + selectionKeys.size());
while(it.hasNext()){
SelectionKey selectionKey = it.next();
it.remove();
//处理传过来的数据
handleData(selectionKey);
}
}
}
private void handleData(SelectionKey key) throws IOException{
if(key.isAcceptable()){
System.out.println("Accepting......");
SocketChannel channel = ((ServerSocketChannel)key.channel()).accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
}else if(key.isReadable()){
System.out.println("Reading......");
SocketChannel channel = (SocketChannel) key.channel();
receiveBuffer.clear();
int count = channel.read(receiveBuffer);
if(count>0){
String receiveText = new String(receiveBuffer.array(),0,count);
System.out.println("客户端传递的内容:"+receiveText);
channel.register(selector, SelectionKey.OP_WRITE);
}
}else if(key.isWritable()){
System.out.println("Writting......");
SocketChannel channel = (SocketChannel) key.channel();
sendBuffer.clear();
sendBuffer.put(new String("这是测试数据").getBytes());
//将缓冲区各标志复位,因为向里面put了数据,标志被改变,复位到起始位置
sendBuffer.flip();
channel.write(sendBuffer);
channel.close();
}
}
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;
import java.util.Set;
/*
* 自定义服务器
*/
public class NIOServer {
private static int SERVER_PORT = 9000;
private static String SERVER_URI = "127.0.0.1";
private final static int BLOCK = 4096;
private static ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK);
private static ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK);
private ServerSocketChannel serverSocketChannel = null;
private Selector selector = null;
public static void main(String[] args) {
NIOServer server = new NIOServer();
server.start();
}
private void start(){
try {
this.initServer();
this.initService();
} catch (IOException e) {
e.printStackTrace();
}
}
private void initServer(){
try {
serverSocketChannel = ServerSocketChannel.open();
//静态方法 实例化selector
selector = Selector.open();
//设置为非阻塞方式,如果为true 那么就为传统的阻塞方式
serverSocketChannel.configureBlocking(false);
/*
* 通过这个选项,可以使多个Socket对象绑定在同一个端口上。其实这样做并没有多大意义,但当使用close方法关闭Socket连接后,
* Socket对象所绑定的端口并不一定马上释放;系统有时在Socket连接关闭才会再确认一下是否有因为延迟面未到达的数据包,
* 这完全是在底层处理的,也就是说对用户是透明的;因此,在使用Socket类时完全不会感觉到。
* 这种处理机制对于随机绑定端口的Socket对象没有什么影响,
* 但对于绑定在固定端口的Socket对象就可能会抛出“Address already in use: JVM_Bind”例外。
* 因此,使用这个选项可以避免个例外的发生。
*/
serverSocketChannel.socket().setReuseAddress(true);
//绑定端口
serverSocketChannel.socket().bind(new InetSocketAddress(SERVER_URI,SERVER_PORT));
/*
* 设置服务处于可接受信息的状态,即在服务中注册KEY,告诉服务 现在以经处于属于接受状态
*/
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("NIOServer is starting at " + SERVER_PORT + "......");
} catch (IOException e) {
e.printStackTrace();
}
}
private void initService() throws IOException{
while(selector.select()>0){
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectionKeys.iterator();
System.out.println("目前已经接受的key的 size : " + selectionKeys.size());
while(it.hasNext()){
SelectionKey selectionKey = it.next();
it.remove();
//处理传过来的数据
handleData(selectionKey);
}
}
}
private void handleData(SelectionKey key) throws IOException{
if(key.isAcceptable()){
System.out.println("Accepting......");
SocketChannel channel = ((ServerSocketChannel)key.channel()).accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
}else if(key.isReadable()){
System.out.println("Reading......");
SocketChannel channel = (SocketChannel) key.channel();
receiveBuffer.clear();
int count = channel.read(receiveBuffer);
if(count>0){
String receiveText = new String(receiveBuffer.array(),0,count);
System.out.println("客户端传递的内容:"+receiveText);
channel.register(selector, SelectionKey.OP_WRITE);
}
}else if(key.isWritable()){
System.out.println("Writting......");
SocketChannel channel = (SocketChannel) key.channel();
sendBuffer.clear();
sendBuffer.put(new String("这是测试数据").getBytes());
//将缓冲区各标志复位,因为向里面put了数据,标志被改变,复位到起始位置
sendBuffer.flip();
channel.write(sendBuffer);
channel.close();
}
}
}
测试结果如下:
- JAVA -NIO实现(一)
- Java NIO:一、NIO基础
- java nio实例一
- java nio 缓冲区(一)
- java nio 通道(一)
- Java NIO传输(一)
- Java的Nio(一)
- Java NIO介绍(一)
- java NIO(一) 缓冲区
- Java NIO (一)
- java nio(一)概述
- Java NIO (一) 概述
- Java NIO(一)
- java nio基础一
- Java NIO(一)
- java-----NIO总结(一)
- java NIO(一)
- Java NIO (一)--简介
- linux 命令行一些要点(二)
- LeetCode - Interleaving String
- Kendo UI开发教程(15): Kendo MVVM 数据绑定(四) Disabled/Enabled
- MySQL主流存储引擎概述
- 批处理代码遇到路径中间有空格怎么办?
- JAVA -NIO实现(一)
- 内核初始化优化宏(__init, __devinit)
- .NET中实现Word,Excle文档到PDF文档的转化
- jdbc详解(二)
- ios学习笔记:UIAlertView的使用
- Linux USB口的热插拔
- I2C子系统分析
- 阿里巴巴校招内推简历筛选方案(总结篇)
- 一个类似OSGI Declarative Services的c++组件框架