枯燥的講解API沒有意義,也太沒意思了,所以我采取更加直觀的例子來說明API,不嚴謹但更簡單直觀,首先為了方便測試我們利用Channel寫的Client,我們先用簡單的幾行代碼實現一個本地的測試服務器:
package com.company;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args){
//服務器監聽請求的端口
int port = 9999;
ServerSocket server=null;
try {
server = new ServerSocket(port);
}catch( IOException e ){
System.out.println("服務器創建失敗");
e.printStackTrace();
}
Socket temp=null;
try{
temp = server.accept();
}catch( IOException e ){
System.out.println("獲取連接失敗");
e.printStackTrace();
}
OutputStream output = null;
try{
output = temp.getOutputStream();
}catch ( Exception e ){
e.printStackTrace();
}
byte [] buffer = "llin of Tianjin University love JAVA and Alibaba!".getBytes();
while ( true ) {
try {
output.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
try {
//防止傳輸信息過於快,不方便我們測試
Thread.sleep(1000);
}catch ( InterruptedException e ){
e.printStackTrace();
}
}
}
}
主要作用是間隔一段時間向客戶端發送一段信息,用來測試客戶端的channel是否實際發揮了作用
下面是一個例子,可以用來簡單熟悉一下JAVA中的Buffer和Channel接口的使用,雖然實際中這樣使用的意義不大
package com.company;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
/**
* Created by liulin on 16-4-12.
*/
public class TestClient {
//默認的IP
public static final String ipAddress = "127.0.0.1";
//默認端口
public static final int DEFAULT_PORT = 9999;
//緩存的大小
public static final int BUFFER_SIZE = 200;
public static void main ( String [] args ){
if ( args.length == 0 ){//如果沒有給出IP地址那麼沒辦法找到測試服務器啊
System.out.println( "請輸入服務器的IP地址或域名");
}
//給定端口那麼使用指定端口,否則使用默認端口
int port=0;
try{
port = Integer.parseInt(args[1]);
}catch ( Exception e ){
port = DEFAULT_PORT;
e.printStackTrace();
}
try{//本例只是讓大家熟悉JAVA提供的Buffer,Channel的API,讓不熟悉Socket的同學學習下Socket機制
//所以不采用非阻塞機制,也不使用selector
SocketAddress address = new InetSocketAddress( ipAddress , port );
//通過靜態工廠獲得指定address的通道實例
SocketChannel client = SocketChannel.open(address);
//通過靜態工廠獲得指定大小的緩存
ByteBuffer buffer = ByteBuffer.allocate( BUFFER_SIZE );
WritableByteChannel out = Channels.newChannel( System.out );//輸出通道
//從服務器讀取數據
while ( client.read(buffer) != -1 ){
//將緩存的position置為buffer內置數組的初始位置,當前position位置設置為limit
//position,limit,capacity的概念會在專門介紹buffer的博客中一齊講解
//簡單地講,就是告訴buffer,我們要開始從頭讀取/修改你了
buffer.flip();
out.write( buffer );
//為了方便查看調試信息,輸出一個換行
System.out.write( "\n".getBytes());
//只是修改position為buffer內置數組初始位置,limit設置為capacity
//目前可以簡單地理解為清空緩存(詳情我會在專門介紹buffer的博客中一齊講解)
buffer.clear();
}
}catch ( Exception e ){
e.printStackTrace();
}
}
}
主要就是利用Channel連接到服務器並且通過buffer進行讀寫,輸出到控制台的一個簡單的例子,執行效果如下(測試的時候一定要先打開測試服務器):
作為一個有著TDD思維的程序猴子,怎麼能不先寫測試用的客戶端呢….其實只是無恥地在之前客戶端添了一行代碼
package com.company;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
/**
* Created by liulin on 16-4-12.
*/
public class TestClient {
//默認的IP
public static final String ipAddress = "127.0.0.1";
//默認端口
public static final int DEFAULT_PORT = 9999;
//緩存的大小
public static final int BUFFER_SIZE = 200;
public static void main ( String [] args ){
if ( args.length == 0 ){//如果沒有給出IP地址那麼沒辦法找到測試服務器啊
System.out.println( "請輸入服務器的IP地址或域名");
}
//給定端口那麼使用指定端口,否則使用默認端口
int port=0;
try{
port = Integer.parseInt(args[1]);
}catch ( Exception e ){
port = DEFAULT_PORT;
e.printStackTrace();
}
try{//本例只是讓大家熟悉JAVA提供的Buffer,Channel的API,讓不熟悉Socket的同學學習下Socket機制
//所以不采用非阻塞機制,也不使用selector
SocketAddress address = new InetSocketAddress( ipAddress , port );
//通過靜態工廠獲得指定address的通道實例
SocketChannel client = SocketChannel.open(address);
//通過靜態工廠獲得指定大小的緩存
ByteBuffer buffer = ByteBuffer.allocate( BUFFER_SIZE );
WritableByteChannel out = Channels.newChannel( System.out );//輸出通道
//從服務器讀取數據
client.write( ByteBuffer.wrap("testing...".getBytes()));
while ( client.read(buffer) != -1 ){
//將緩存的position置為buffer內置數組的初始位置,當前position位置設置為limit
//position,limit,capacity的概念會在專門介紹buffer的博客中一齊講解
//簡單地講,就是告訴buffer,我們要開始從頭讀取/修改你了
buffer.flip();
out.write( buffer );
//為了方便查看調試信息,輸出一個換行
System.out.write( "\n".getBytes());
//只是修改position為buffer內置數組初始位置,limit設置為capacity
//目前可以簡單地理解為清空緩存(詳情我會在專門介紹buffer的博客中一齊講解)
buffer.clear();
}
}catch ( Exception e ){
e.printStackTrace();
}
}
}
下面是由selector調度的HTTP服務器,講解寫在了注釋中,如果還有不明白的可以在評論中問
package com.company;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
/**
* Created by liulin on 16-4-12.
*/
public class TestClient {
//默認的IP
public static final String ipAddress = "127.0.0.1";
//默認端口
public static final int DEFAULT_PORT = 9999;
//緩存的大小
public static final int BUFFER_SIZE = 200;
public static void main ( String [] args ){
if ( args.length == 0 ){//如果沒有給出IP地址那麼沒辦法找到測試服務器啊
System.out.println( "請輸入服務器的IP地址或域名");
}
//給定端口那麼使用指定端口,否則使用默認端口
int port=0;
try{
port = Integer.parseInt(args[1]);
}catch ( Exception e ){
port = DEFAULT_PORT;
e.printStackTrace();
}
try{//本例只是讓大家熟悉JAVA提供的Buffer,Channel的API,讓不熟悉Socket的同學學習下Socket機制
//所以不采用非阻塞機制,也不使用selector
SocketAddress address = new InetSocketAddress( ipAddress , port );
//通過靜態工廠獲得指定address的通道實例
SocketChannel client = SocketChannel.open(address);
//通過靜態工廠獲得指定大小的緩存
ByteBuffer buffer = ByteBuffer.allocate( BUFFER_SIZE );
WritableByteChannel out = Channels.newChannel( System.out );//輸出通道
//從服務器讀取數據
client.write( ByteBuffer.wrap("testing...".getBytes()));
while ( client.read(buffer) != -1 ){
//將緩存的position置為buffer內置數組的初始位置,當前position位置設置為limit
//position,limit,capacity的概念會在專門介紹buffer的博客中一齊講解
//簡單地講,就是告訴buffer,我們要開始從頭讀取/修改你了
buffer.flip();
out.write( buffer );
//為了方便查看調試信息,輸出一個換行
System.out.write( "\n".getBytes());
//只是修改position為buffer內置數組初始位置,limit設置為capacity
//目前可以簡單地理解為清空緩存(詳情我會在專門介紹buffer的博客中一齊講解)
buffer.clear();
}
}catch ( Exception e ){
e.printStackTrace();
}
}
}
測試結果如下: