当前位置:编程学习 > JAVA >>

3种下载文件程序的思考,为何使用NIO进行异步网络通讯

1.  前言
现在很多做网络通讯中间代理层的通讯都是使用Java1.4以后推出的NIO进行编写,现在还有很多开源的框架也是封装了NIO的书写细节来帮助大家简写异步非阻塞通讯服务。像MySql的代理中间件amoeba-mysql-proxy就是采用NIO的方式处理client端过来的request,之后与Mysql-Server层的通讯也是采用NIO进行命令消息发送的。再看咱们JavaEye首页介绍的项目xmemcached,其中作者Dennis是其xmemcached的开发人,他也是通过NIO的方式与memcached的Server进行异步通讯的,Dennis的另一个项目yanf4j就是一个NIO框架,xmemcache也是借助这个NIO框架实现的异步非阻塞方式的网络通讯,Apache的MINA框架都是NIO的封装再实现。
那么我们就来回顾一下以前的处理方式,来看看为什么现在要使用NIO来进行异步非阻塞方式的通讯吧,网上很多文章都是几句话将NIO和原始的socket通讯的优劣一带而过,我们这次用一个简单的下载大文件的网络服务程序进行说明。使用3种模式来说明,分别是同步单独线程服务运行模式、传统阻塞多线程模式、使用NIO异步非阻塞模式。
我们设置服务器上有一个1.81GB的电影,格式为RMVB。使用Server进行服务监听,客户端请求到Server,建立网络通讯,进行电影下载。
2.  同步单线程阻塞
使用同步单线程下载,是最原始的socket通讯,服务端的代码如下
Java代码 
<span style="font-size: x-small;">package server; 
 
import java.io.FileInputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
 
/**
 * liuyan
 */ 
public class FilmServer { 
 
    public static void main(String[] args) { 
        FilmServer ms = new FilmServer(); 
        try { 
            ms.server(); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 
    /**
     * 服务器端响应请求
     * 
     * @throws Exception
     */ 
    public void server() throws Exception { 
 
        // 0.建立服务器端的server的socket 
        ServerSocket ss = new ServerSocket(9999); 
 
        while (true) { 
 
            // 1.打开socket连接 
            // 等待客户端的请求 
            final Socket server = ss.accept(); 
 
            System.out.println("服务-----------请求开始start"); 
 
            // 2.打开socket的流信息,准备下面的操作 
            final InputStream is = server.getInputStream(); 
            byte b[] = new byte[1024]; 
 
            int readCount = is.read(b); 
 
            String str = new String(b); 
 
            str = str.trim(); 
 
            final String serverFileName = str; 
 
            // 3.对流信息进行读写操作 
            System.out.println("客户端传过来的信息是:" + str); 
 
            System.out.println("线程" + Thread.currentThread().getName() + "启动"); 
 
            try { 
 
                FileInputStream fileInputStream = new FileInputStream( 
                        serverFileName); 
 
                // 3.1 服务器回复客户端信息(response) 
                OutputStream os = server.getOutputStream(); 
 
                byte[] bfile = new byte[1024]; 
 
                // 往客户端写 
                while (fileInputStream.read(bfile) > 0) { 
                    os.write(bfile); 
                } 
 
                fileInputStream.close(); 
 
                os.close(); 
 
                // 4.关闭socket 
                // 先关闭输入流 
                is.close(); 
 
                // 最后关闭socket 
                server.close(); 
 
            } catch (Exception e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
 
            System.out.println("服务-----------请求结束over"); 
        } 
 
    } 
 
}</span> 
 服务端这么写代码会有什么问题?咱们先来看客户端代码,之后运行后就知道了。
Java代码 
<span style="font-size: x-small;">package client; 
 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.Socket; 
import java.net.UnknownHostException; 
 
/**
 * liuyan
 * @version 1.0
 */ 
public class FilmClient { 
    public static void main(String[] args) { 
        for (int i = 1; i <= 2; i++) { 
       &nb

补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,