[TOC]
抢先体验运行效果
Server
public class SelectorServer {
private static Selector selector ;
public static void main(String[] args) {
ServerSocketChannel serverChannel = null;
try {
serverChannel = ServerSocketChannel.open();
serverChannel.socket().setReuseAddress(true);
serverChannel.socket().bind(new InetSocketAddress(3467));
serverChannel.configureBlocking(false); // none blocking mode
selector = SelectorProvider.provider()
.openSelector();
Iterator<SelectionKey> selectorKeys = null;
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// selector mode
// 阻塞选择操作, n 已经准备好的通道的个数。
int n = selector.select();
if (n == 0) {
continue;
}
selectorKeys = selector.selectedKeys().iterator();
SelectionKey oneKey = null;
while (selectorKeys.hasNext()) {
try{
oneKey = selectorKeys.next();
selectorKeys.remove();
handleSelectorKey(oneKey);
}finally{
try{
if(oneKey != null && oneKey.isWritable()){
oneKey.cancel();
oneKey.channel().close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClosedSelectorException e) {
e.printStackTrace();
}
finally {
}
}
static ByteBuffer readerBuffer ;
private synchronized static void handleSelectorKey(SelectionKey key) {
if(key == null){
return;
}
if (key.isAcceptable()) {
System.out.println("selection acceptable --> " + key.isValid());
handleSelectionAcceptable(key);
}
if (key.isConnectable()) {
System.out.println("selection connectable --> " + key.isValid());
handleSelectionAcceptable(key);
}
if (key.isReadable()) {
System.out.println("selection readable --> " + key.isValid());
synchronized (SelectorServer.class) {
readerBuffer = handleSelectionReadable(key);
}
}
if (key.isWritable()) {
System.out.println("selection writeable --> " + key.isValid());
synchronized (SelectorServer.class) {
handleSelectionWriteable(key,readerBuffer);
}
}
}
public static void handleSelectionAcceptable(SelectionKey key) {
if(key == null) return;
try{
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = (SocketChannel) ssc.accept();
System.out.println("receive connection request " +
sc.socket().getInetAddress()+":"+sc.socket().getPort());
sc.configureBlocking(false);
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("attachment added by myself .".getBytes());
buffer.flip();
sc.register(selector, SelectionKey.OP_READ,buffer);
}catch(IOException e){
}
}
public static void handleSelectionCollectable(SelectionKey key) {
}
public static ByteBuffer handleSelectionReadable(SelectionKey key) {
ByteBuffer buffer = (ByteBuffer) key.attachment();
if(buffer != null){
System.out.println("attachment data===== : " + getString(buffer));
buffer.rewind();
}
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
try {
sc.read(readBuffer);
sc.register(selector, SelectionKey.OP_WRITE,buffer);
} catch (IOException e) {
e.printStackTrace();
}
readBuffer.flip();
String data = getString(readBuffer);
System.out.println("receive data from client --->: "
+ data+" == "+ sc.socket().getInetAddress()
+" :"+sc.socket().getPort());
readBuffer.rewind();
return readBuffer;
}
public static String getString(ByteBuffer buffer)
{
if(buffer ==null){
return "";
}
Charset charset = null;
CharsetDecoder decoder = null;
CharBuffer charBuffer = null;
try
{
charset = Charset.forName("UTF-8");
decoder = charset.newDecoder();
charBuffer = decoder.decode(buffer);//用这个的话,只能输出来一次结果,第二次显示为空
String s = charBuffer.toString();
System.out.println("buffer to string : len : " + s.length() +" ;data: " + s);
return charBuffer.toString().trim();
}
catch (Exception ex)
{
ex.printStackTrace();
return "";
}
}
public static void handleSelectionWriteable(SelectionKey key,ByteBuffer readBuffer) {
String toClientData = "echo server : "+getString(readBuffer);
byte serverEcho[] = toClientData.getBytes(Charset.forName("utf-8"));
ByteBuffer writeBuffer = ByteBuffer.wrap(serverEcho);
SocketChannel sc = (SocketChannel) key.channel();
try {
sc.write(writeBuffer);
System.out.println("to client data--->: " + toClientData
+" == "+ sc.socket().getInetAddress()
+" :"+sc.socket().getPort());
} catch (IOException e) {
e.printStackTrace();
System.out.println(e);
}finally {
}
}
}
client
public class SocketChannelClient extends Thread{
public static final String SERVER_ADDRESS = "localhost";
public static final int SERVER_PORT = 3467;
private final String address;
private final int port ;
SocketChannel socketChannel;
Selector selector;
public SocketChannelClient(String remoteAdress , int remotePort){
address = remoteAdress;
port = remotePort;
}
public static void main(String[] args) {
SocketChannelClient client = new SocketChannelClient(SocketChannelClient.SERVER_ADDRESS,
SocketChannelClient.SERVER_PORT);
client.start();
}
@Override
public void run() {
try{
socketChannel = SocketChannel.open(new InetSocketAddress(address,port));
socketChannel.configureBlocking(false);
selector = SelectorProvider.provider().openSelector();
socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
Iterator<SelectionKey> keyIterator;
SelectionKey oneKey = null;
while(true){
int n = selector.select();
if(n == 0){
continue;
}
keyIterator = selector.selectedKeys().iterator();
while(keyIterator.hasNext()){
try{
oneKey = keyIterator.next();
keyIterator.remove();
handleSelectorKey(oneKey);
}finally{
try{
if(oneKey != null && oneKey.isReadable()){
oneKey.channel().close();
oneKey = null;
}
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}catch(IOException e){
e.printStackTrace();
}
}
private synchronized void handleSelectorKey(SelectionKey key) {
if(key == null){
return;
}
if (key.isAcceptable()) {
System.out.println("selection acceptable --> " + key);
handleSelectionAcceptable(key);
}
if (key.isConnectable()) {
System.out.println("selection connectable --> " + key);
handleSelectionAcceptable(key);
}
if (key.isReadable()) {
System.out.println("selection readable --> " + key);
handleSelectionReadable(key);
}
if (key.isWritable()) {
System.out.println("selection writeable --> " + key);
handleSelectionWriteable(key);
}
}
public void handleSelectionAcceptable(SelectionKey key) {
if(key == null) return;
try{
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = (SocketChannel) ssc.accept();
System.out.println("receive connection request " +
sc.socket().getInetAddress()+":"+sc.socket().getPort());
sc.configureBlocking(false);
ByteBuffer buffer = ByteBuffer.allocate(1024);
sc.register(selector, SelectionKey.OP_READ,buffer);
}catch(IOException e){
}
}
public void handleSelectionCollectable(SelectionKey key) {
}
public void handleSelectionReadable(SelectionKey key) {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
try {
sc.read(readBuffer);
} catch (IOException e) {
e.printStackTrace();
}finally {
}
readBuffer.flip();
System.out.println("receive data from server --->: "
+ getString(readBuffer));
}
public static String getString(ByteBuffer buffer)
{
Charset charset = null;
CharsetDecoder decoder = null;
CharBuffer charBuffer = null;
try
{
charset = Charset.forName("UTF-8");
decoder = charset.newDecoder();
charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
return charBuffer.toString();
}
catch (Exception ex)
{
ex.printStackTrace();
return "";
}
}
static int talkValue = 0;
ByteBuffer sendBuffer;
public void handleSelectionWriteable(SelectionKey key) {
sendBuffer = ByteBuffer.wrap(("talk to server "+(++talkValue)).getBytes(Charset.forName("utf-8")));
key.attach(sendBuffer);
SocketChannel sc = (SocketChannel) key.channel();
try {
sc.write(sendBuffer);
key.interestOps(SelectionKey.OP_READ);
} catch (IOException e) {
e.printStackTrace();
}finally {
}
}
}