NIO系列(四)——socket通道和serversocket通道
SocketChannel
SocketChannel是一個連線到tcp網路套接字的通道。可以通過以下2中方式建立
1.開啟一個SocketChannel並連線到網際網路上的某臺伺服器。
SocketChannel client = SocketChannel.open(new InetSocketAddress("127.0.0.1",10699));
2.ServerSocketChannel獲得一個網路連線。
SocketChannel connctClient = server.accept();
建立SocketChannel
通過SocketChannel.Open()方法建立通道,open()方法可以傳入連線物件的引數。
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("192.168.1.107",9999));
關閉SocketChannel
通過close()方法關閉通道。
socketChannel.close();
socketChannel接收資訊
可以通過read()方法把通道資料讀到快取中。
ByteBuffer bBuffer = ByteBuffer.allocate(48); int readSize; do { readSize = socketChannel.read(bBuffer); bBuffer.flip(); System.out.println(Charset.forName("UTF-8").decode(bBuffer)); bBuffer.clear(); } while (readSize != -1);
read()返回的int值表示讀到快取資料的長度,當返回值為-1時,表示到了流的末尾。
SocketChannel傳送資訊
通過write()方法將快取資料寫入到通道內,write()無法保證一次向通道中寫入多少資料,所以要迴圈判斷hasRemainning(),直到沒有資料寫入。
ByteBuffer bBuffer = ByteBuffer.wrap(("伺服器" + server + "連線成功").getBytes());
while (bBuffer.hasRemaining()){
socketChannel.write(bBuffer);
}
非阻塞設定
SocketChannel可以通過configureBlocking()方法設定成非阻塞。
socketChannel.configureBlocking(false);
例子
這個例子是與192.168.1.107:9999建立連線並接收一次傳送資料。
public voidtestClient() {
try {
SocketChannelsocketChannel= SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("192.168.1.107",9999));
ByteBufferbBuffer= ByteBuffer.allocate(48);
int readSize;
do {
readSize = socketChannel.read(bBuffer);
bBuffer.flip();
System.out.println(Charset.forName("UTF-8").decode(bBuffer));
bBuffer.clear();
}while(readSize!= -1);
socketChannel.close();
}catch(IOException e) {
e.printStackTrace();
}
}
ServerSocketChannel
Java NIO的ServerSocketChannel是一個可以監聽新進來的TCP連線的通道,就像標準IO的ServerSocket一樣。
建立ServerSocketChannel
通過ServerSocketChannel.open()建立通道
ServerSocketChannel server = ServerSocketChannel.open();
server.socket().bind(new InetSocketAddress(9999));
server.socket().bind(SocketAddressendpoint, int backlog)可以傳兩個引數,第二個引數是,限制最大連線數。
獲得連線
通過accept()方法,獲得socket連線
SocketChannel socketChannel = server.accept();
傳送資料和接收資料都通過SocketChannel進行。
關閉ServerSocketChannel
通過close()方法關閉通道
server.close();
非阻塞設定
ServerSocketChannel可以設定成非阻塞模式。在非阻塞模式下,accept會立即返回,所以要判斷SocketChannel是否為空。
server.configureBlocking(false);
while (true){
SocketChannelsocketChannel= server.accept();
if (socketChannel != null) {
}
}
例子
這個例子先繫結監聽9999埠,但有socket連線時,會發送一條資料。
public voidtestServer() {
try {
ServerSocketChannelserver= ServerSocketChannel.open();
server.socket().bind(newInetSocketAddress(9999));
System.out.println("服務端啟動成功");
server.configureBlocking(false);
while (true) {
SocketChannelsocketChannel= server.accept();
if (socketChannel != null) {
System.out.println(socketChannel + "連線成功");
ByteBufferbBuffer= ByteBuffer.wrap(("伺服器" + server + "連線成功").getBytes());
while (bBuffer.hasRemaining()) {
socketChannel.write(bBuffer);
}
}
}
}catch(IOException e) {
e.printStackTrace();
}
}