您的位置:首页 > 理论基础 > 计算机网络

使用NIO在网络上传输文件

2017-12-26 14:59 162 查看
NIO,官方说法为New IO,我们也可以理解为Non Blocking IO。NIO需要JDK1.7以上支持。

package channel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import org.junit.Test;

public class TestNIO {

@Test
public void client(){
try {
SocketChannel sc = SocketChannel.
open(new InetSocketAddress("127.0.0.1", 8080));
//设置为非阻塞模式
sc.configureBlocking(false);
FileInputStream fis = new FileInputStream(new File("1.jpg"));
FileChannel inChannel = fis.getChannel();
ByteBuffer dst = ByteBuffer.allocate(1024);
while(inChannel.read(dst) != -1){
dst.flip();
sc.write(dst);
dst.clear();
}
inChannel.close();
fis.close();
sc.close();

} catch (IOException e) {
e.printStackTrace();
}
}

@Test
public void test2(){
try {
SocketChannel sc = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8080));
sc.configureBlocking(false);
ByteBuffer src = ByteBuffer.allocate(1024);
src.put(new Date().toString().getBytes());
src.flip();
sc.write(src);
src.clear();
sc.close();
} catch (IOException e) {
e.printStackTrace();
}
}

@Test
public void server(){
try {
ServerSocketChannel ssc = ServerSocketChannel.open();//1
//设置为非阻塞模式
ssc.configureBlocking(false);//2
ssc.bind(new InetSocketAddress(8080));//3
ByteBuffer buf = ByteBuffer.allocate(1024);
FileOutputStream fos = new FileOutputStream(new File("2.jpg"));
FileChannel outChannel = fos.getChannel();
SocketChannel sc = null;
//用open()获取选择器
Selector selector = Selector.open();//4
/**注册通道到选择器上,指定监控状态(SelectionKey选择键)
* SelectionKey.OP_ACCEPT---接收事件
* SelectionKey.OP_CONNECT---连接事件
* SelectionKey.OP_READ---读事件
* SelectionKey.OP_WRITE---写事件
* 若监听事件不止一个时,可以使用"位或"操作符连接;
int ops = SelectionKey.OP_ACCEPT | SelectionKey.OP_READ;
*/
ssc.register(selector, SelectionKey.OP_ACCEPT);//5
//轮询获取选择器上准备就序的监听事件
while(selector.select() > 0){//selector.select()>0说明至少有一个通道准备就序
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> its = keys.iterator();
while(its.hasNext()){
SelectionKey selectionKey = its.next();
//遍历所有准备就序的监听事件SelectionKey,并进行判断
if(selectionKey.isAcceptable()){//可以启动单独的线程来处理
//若接收就序就打开服务端连接
sc = ssc.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
//...后序读操作
}else if(selectionKey.isConnectable()){
//可以启动单独的线程来处理

}else if(selectionKey.isReadable()){//可以启动单独的线程来处理
sc = (SocketChannel) selectionKey.channel();
//sc.configureBlocking(false);
//sc.register(selector, SelectionKey.OP_READ);
int len = -1;
while((len = sc.read(buf))!= -1){
buf.flip();
outChannel.write(buf);
buf.clear();
}
}else if(selectionKey.isWritable()){
//可以启动单独的线程来处理
}
}
//selectionKey用完后取消掉
its.remove();
}

outChannel.close();
fos.close();
sc.close();
ssc.close();
} catch (IOException e) {
e.printStackTrace();
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐