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);
}
}