Java NIO(非同步IO)Socket通訊例子
簡要說明下:使用java nio開發網路通訊 是比較快速和方面的。因為他可以不用阻塞的方式偵聽客戶端的連線 ,在java nio中可以使用基於事件的機制進行非阻塞通訊,當有新的事
件進行註冊時 我們只需要通過事件偵聽機制 獲取新的事件
簡單的說就是 java nio中裡面有一個selector 非同步 I/O 中的核心物件名為 Selector。Selector 就是您註冊對各種 I/O 事件的興趣的地方,而且當那些事件發生時,就是這個物件告訴
您所發生的事件。
我們先給出一個例子把:
package org.web.niotest;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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;
/**
* java NIO 伺服器端例子
* @author user
*
*/
public class Server {
//伺服器端通道
ServerSocketChannel ssc;
public void start(){
try {
//非同步IO的核心物件名selector 具有事件偵聽的效果
//selector就是您註冊對各種io事件的興趣的地方 而且當那些事件發生時 就是這個物件告訴您所發生的事情
Selector selector=Selector.open();
//開啟一個serversocketchannel通道
ServerSocketChannel ssc=ServerSocketChannel.open();
//設為非同步
ssc.configureBlocking(false);
//繫結埠
ServerSocket ss=ssc.socket();
InetSocketAddress address=new InetSocketAddress(5555);
ss.bind(address);
//註冊事件 regisiter的第一個引數總是selector 第二個總是op_accept 這裡他指定我們要監聽accept事件
//也就是當有新的連結進來是發生的事件
ssc.register(selector,SelectionKey.OP_ACCEPT);
System.out.println("埠註冊完成");
while(true){
//select()這個方法會阻塞 直到有一個已註冊的事件發生 當一個或者更多的事件註冊進來的時候 這個會返回事件的數量
selector.select();
//呼叫selectedKeys()會返回事件物件集合
Set<SelectionKey> selectionKeys=selector.selectedKeys();
//然後我們迭代處理每一個事件
Iterator<SelectionKey> iter=selectionKeys.iterator();
ByteBuffer echoBuffer=ByteBuffer.allocate(20);
SocketChannel sc;
while(iter.hasNext()){
SelectionKey key=iter.next();
//判斷事件型別
if((key.readyOps()&SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT)
{
ServerSocketChannel nssc=(ServerSocketChannel)key.channel();
sc=nssc.accept();
//設為非阻塞
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
iter.remove();
System.out.println("有新的連結"+sc);
}else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ) {
sc=(SocketChannel)key.channel();
while(true){
echoBuffer.clear();
int a=sc.read(echoBuffer);
if(a==-1)
break;
if(a>0){
byte[] b=echoBuffer.array();
System.out.println("接收資料: "+new String(b));
echoBuffer.flip();
sc.write(echoBuffer);
System.out.println("返回資料: "+new String(b));
}
}
sc.close();
System.out.println("連線結束");
System.out.println("=============================");
iter.remove();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]){
new Server().start();
}
}
客戶端的程式碼
package org.web.niotest;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class Client {
public void start() {
try {
SocketAddress address = new InetSocketAddress("localhost", 5555);
SocketChannel client = SocketChannel.open(address);
client.configureBlocking(false);
String a = "asdasdasdasddffasfas";
ByteBuffer buffer = ByteBuffer.allocate(20);
buffer.put(a.getBytes());
buffer.clear();
int d = client.write(buffer);
System.out.println("傳送資料: " + new String(buffer.array()));
while (true) {
buffer.flip();
int i = client.read(buffer);
if (i > 0) {
byte[] b = buffer.array();
System.out.println("接收資料: " + new String(b));
client.close();
System.out.println("連線關閉!");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]){
new Client().start();
}
}