NIO(4) SocketChannel

      Java NIO中的SocketChannel是一個連接到TCP網絡套接字的通道。可以通過以下2種方式創建SocketChannel:
            1、打開一個SocketChannel並連接到互聯網上的某臺服務器。
            2、一個新連接到達ServerSocketChannel時,會創建一個SocketChannel。

通過client發送數據,server進行求和來使用SocketChannel

  • 服務端
<span style="font-family:Times New Roman;">  

package com.zz.socketChannel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class NioServer {

    // 獲取緩衝區
    private ByteBuffer buf = ByteBuffer.allocate(512);
    // 創建一個int緩衝區的視圖,此緩衝區內容的更改在新緩衝區中是可見的(buf和intBuf之間可見),反之亦然
    private IntBuffer intBuf = buf.asIntBuffer();

    private SocketChannel clientChannel = null;
    private ServerSocketChannel serverChannel = null;

    /** 1、打開SocketChannel*/
    private void openChannel() {
        try {
            // 打開ServerSocketChannel通道
            this.serverChannel = ServerSocketChannel.open();
            /**
             * ServerSocketChannel可以設置成非阻塞模式。
             * 在非阻塞模式下,accept() 方法會立刻返回,如果還沒有新進來的連接,返回的將是null。 因此,需要檢查返回的SocketChannel是否是null
             */
            this.serverChannel.configureBlocking(false);
            // 爲socketChannel設置訪問的端口
            this.serverChannel.bind(new InetSocketAddress(8888));
            System.out.println("ServerSocketChannel open...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** 等待客戶端的請求連接 */
    private void waitReqConn() {
        while (true) {
            try {
                /**
                 * 通過 ServerSocketChannel.accept() 方法監聽新進來的連接。
                 * 當 accept()方法返回的時候,它返回一個包含新進來的連接的 SocketChannel。 accept()方法會一直阻塞到有新連接到達
                 */
                this.clientChannel = this.serverChannel.accept();
                if (null != this.clientChannel) {
                    System.out.println("a new client coming.");
                    this.processReq();

                    this.clientChannel.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /** 處理請求過來的數據 */
    private void processReq() {
        System.out.println("start process client's data.");
        try {
            // 調用clear()方法,position將被設回0,limit被設置成 capacity的值(這裏是512)
            this.buf.clear();
            this.clientChannel.read(buf);
            int result = intBuf.get(0) + intBuf.get(1);
            // flip方法將Buffer從寫模式切換到讀模式。調用flip()方法會將position設回0,並將limit設置成之前寫模式下position的值
            buf.flip();
            buf.clear();
            intBuf.put(0, result);
            // 向clientChannel發送數據
            this.clientChannel.write(buf);
            System.out.println("process data complete");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** 啓動 */
    private void start() {
        this.openChannel();
        this.waitReqConn();
    }

    public static void main(String[] args) {
        new NioServer().start();
    }
}
</span>


  • 客服端
package com.zz.socketChannel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.channels.SocketChannel;

public class NioClient {

    private SocketChannel channel = null;
    private ByteBuffer buf = ByteBuffer.allocate(512);
    private IntBuffer intBuf = buf.asIntBuffer();

    private String addr;
    private int port;

    public NioClient(String addr, int port) {
        super();
        this.addr = addr;
        this.port = port;
    }

    /** 與服務器建立連接通道  */
    private SocketChannel connect() throws IOException {
        return SocketChannel.open(new InetSocketAddress(addr, port));
    }

    /** 發送請求到服務器 */
    private void sendReq(int a, int b) throws IOException {
        this.buf.clear();
        this.intBuf.put(0, a);
        this.intBuf.put(1, b);
        // 向服務器發送數據
        this.channel.write(buf);
    }

    /** 接收服務器運算的結果  */
    private int recvServerResult() throws IOException {
        this.buf.clear();
        this.channel.read(buf);

        return intBuf.get(0);
    }

    /** 開始啓動 */
    public int start(int a, int b) {
        int result = 0;

        try {
            this.channel = this.connect();
            this.sendReq(a, b);
            result = this.recvServerResult();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    public static void main(String[] args) {
        int result = new NioClient("127.0.0.1", 8888).start(99, 101);
        System.out.println("服務器計算結果爲:" + result);
    }
}
發佈了59 篇原創文章 · 獲贊 7 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章