public class NioServer {
private static final int SERVERPORT = 8080;
public static void main(String[] args) {
Selector selector = null;
ServerSocketChannel server = null;
try {
selector = Selector.open();
server = ServerSocketChannel.open();
InetSocketAddress ip = new InetSocketAddress(SERVERPORT);
server.socket().bind(ip);
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服務器開始接受客戶端連接");
while (true) {
int channelNum = selector.select(1);
if (channelNum == 0) {
continue;
}
// 一個選擇器負責多個通過channel ,多個channel意味着多個socket連接
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
if (key.isAcceptable()) {
ServerSocketChannel server2 = (ServerSocketChannel) key.channel();
SocketChannel channel = server2.accept();
channel.configureBlocking(false);
//客戶端來連接後,標記管道是可以讀或寫的,因爲服務端也要讀或寫 key.isReadable()
channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
System.out.println("客戶端:"
+ channel.socket().getInetAddress().getHostName() + ":"
+ channel.socket().getPort() + " 連接上了");
}
// readable
if (key.isReadable()) { //包含了事件的狀態信息和時間對應的通道的綁定
// System.out.println("可讀");
SocketChannel channel = (SocketChannel) key.channel();
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
ByteBuffer buffer = ByteBuffer.allocate(50);
try {
channel.read(buffer);
} catch (IOException e) {
// 客戶端異常斷開連接
System.out.println("客戶端:"
+ channel.socket().getInetAddress().getHostName() + ":"
+ channel.socket().getPort() + " 已斷開連接");
channel.close();
continue;
}
buffer.flip();
String msg = decoder.decode(buffer).toString();
if (msg.equals("退出!@#$%")) {
// 客戶端主動斷開連接
System.out.println("客戶端:"
+ channel.socket().getInetAddress().getHostName() + ":"
+ channel.socket().getPort() + " 已斷開連接");
channel.close();
continue;
}
System.out.println(
channel.socket().getInetAddress().getHostName() + ":"
+ channel.socket().getPort() + ":" + msg);
if (key.isWritable()) {
CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
try {
channel.write(encoder.encode(CharBuffer.wrap("server receive your message ")));
} catch (IOException e) {
// TODO: handle exception
System.out.println("寫入io錯誤");
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
selector.close();
server.close();
} catch (IOException e) {
}
}
}
}
public class NioClient {
public static void main(String[] args) {
ClientThread client = new ClientThread();
client.start();
BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
try{
String readline;
while((readline = sin.readLine())!=null){
if(readline.equals("bye")){
client.close();
System.exit(0);
}
client.send(readline);
}
}catch(IOException e){
e.printStackTrace();
}
try {
Class cls = Class.forName("actions.dispatcher.nio.NioClient");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Method meth = cls.getMethod("add", partypes);
NioClient methobj = new NioClient();
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = meth.invoke(methobj, arglist);
Integer retval = (Integer) retobj;
System.out.println(retval.intValue());
} catch (Throwable e) {
System.err.println(e);
}
}
public int add(int a,int b){
return a+b;
}
}
public class ClientThread extends Thread{
private CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
private CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
private Selector selector = null;
private SocketChannel socket = null;
private SelectionKey clientKey = null;
public ClientThread(){
try{
selector = Selector.open();
socket = SocketChannel.open();
socket.configureBlocking(false);
clientKey = socket.register(selector, SelectionKey.OP_CONNECT);
InetSocketAddress ip = new InetSocketAddress("localhost",8080);
System.out.println(socket.connect(ip));
}catch(IOException e){
e.printStackTrace();
}
}
public void run(){
try{
while(true){
int prepareIoChannelNum=selector.select(1); //選擇準備io操作的channel
if(prepareIoChannelNum==0){
continue;
}
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while(it.hasNext()){
SelectionKey key = it.next();
it.remove();
if(key.isConnectable()){
SocketChannel channel = (SocketChannel)key.channel();
if(channel.isConnectionPending())
channel.finishConnect();
channel.register(selector, SelectionKey.OP_READ);//告訴選擇器,客戶端要對讀數據channel感興趣
System.out.println("連接服務器端成功!");
}else if(key.isReadable()){
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(50);
try{
channel.read(buffer);
}catch(IOException e){
System.out.println("與服務器:"
+ channel.socket().getInetAddress().getHostName() + ":"
+ channel.socket().getPort() + "的連接已斷開");
channel.close();
continue;//這一句是爲了讓你看到打印信息
}
buffer.flip();
String msg = decoder.decode(buffer).toString();
System.out.println(
channel.socket().getInetAddress().getHostName() + ":"
+ channel.socket().getPort() + ":" + msg);
}
}
}
}catch(IOException e){
e.printStackTrace();
}
finally{
try{
selector.close();
socket.close();
}catch(IOException e){}
}
}
public void send(String msg){
try{
SocketChannel client = (SocketChannel)clientKey.channel();
client.write(encoder.encode(CharBuffer.wrap(msg)));
}catch(Exception e){
System.out.println("發送信息失敗");
e.printStackTrace();
}
}
public void close(){
try{
selector.close();
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}