2.1Java 阻塞式io程式設計
阿新 • • 發佈:2018-12-12
Java 阻塞式io程式設計
執行流程
總體流程圖
1.Server
- 建立連線(ServerSocketChannel)
- 開啟埠(SocketAddress)並繫結bind()
- 迴圈監聽 1)等待請求連線serversocketchannel.accept() 【發生阻塞】 2)每個SocketChannel開啟執行緒讀取資料。
2.Client
- 開啟socketChannel
- 建立連線socketChannel.connect(地址,埠)
- 開始傳送和接受資料。
程式碼
Server
public class Server {
public static void main( String[] args) throws IOException {
// 開啟Socket
ServerSocketChannel serversocketchannel = ServerSocketChannel.open();
// 開啟埠
SocketAddress socketAddress = new InetSocketAddress(8080);
// 監聽8080 埠進來的tcp連線
serversocketchannel.socket().bind(socketAddress);
// 開啟迴圈監聽
while(true){
// 這裡會阻塞,直到有請求連線
SocketChannel socketChannel = serversocketchannel.accept();
// 開啟新的執行緒來處理這個請求,然後while迴圈監聽8080埠
SocketHandler handler = new SocketHandler(socketChannel);
new Thread(handler).start();
}
}
}
SocketHandler處理資料
public class SocketHandler implements Runnable{
private SocketChannel socketChannel;
public SocketHandler(SocketChannel socketChannel){
this.socketChannel = socketChannel;
}
public void run() {
// 堆空間中分配緩衝區
ByteBuffer buffer = ByteBuffer.allocate(1024);
try {
// 將請求資料讀入Buffer中
int num ;
// 如果有資料
while ((num = socketChannel.read(buffer))>0){
// 讀取Buffer內容之前先flip一下
// Buffer 切換為讀模式
buffer.flip();
// 加快讀取速度
byte[] bytes = new byte[num];
// 讀取資料
buffer.get(bytes);
String result = new String (bytes,"UTF-8");
System.out.println("收到請求:"+result);
// 回覆客戶端
// warp用於存放在byte陣列
ByteBuffer writeBuffer = ByteBuffer.wrap(("我已經收到你的請求,你的請求內容是:" + result).getBytes());
socketChannel.write(writeBuffer);
buffer.clear();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
client
public class Client {
public static void main(String[] args) {
try {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost",8080));
// 傳送請求
ByteBuffer buffer = ByteBuffer.wrap("test".getBytes());
socketChannel.write(buffer);
// 獲取server響應
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int num ;
if((num = socketChannel.read(readBuffer))> 0 ){
readBuffer.flip();
byte[] result = new byte[num];
readBuffer.get(result);
String demo = new String(result,"UTF-8");
System.out.println("返回值:"+demo);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
結果展示和分析
執行結構 Server client
阻塞io的缺點
- 每次連線都要新開執行緒(accept()方法開執行緒處理。)
- accept() 是一個阻塞操作,