在Java中使用NIO进行网络编程

在JDK中,有一个非常有意思的库:NIO(New I/O)。这个库中有3个重要的类,分别 是java.nio.channels中Selector和Channel,以及java.nio中的Buffer。

本篇文章我们首先了解一下为什么需要NIO来进行网络编程,然后看看一步一步来讲解 如何在网络编程中使用NIO。

为什么需要NIO

使用Java编写过Socket程序的同学一定都知道Socket和SocketServer。当调用某个调 用的时候,调用的地方就会阻塞,等待响应。这种方式对于小规模的程序非常方便,但是 对于大型的程序就有点力不从心了,当有大量的连接的时候,我们可以为每一个连接建立 一个线程来操作。但是这种做法带来的缺陷也是显而易见的:

1.硬件能够支持大量的并发。

2.并发的数量始终有一个上限。

3.各个线程之间的优先级不好控制。

4.各个Client之间的交互与同步困难。

我们也可以使用一个线程来处理所有的请求,使用不阻塞的IO,轮询查询所有的 Client。这种做法同样也有缺陷:无法迅速响应Client端,同时会消耗大量轮询查询的时 间。

所以,我们需要一种poll的模式来处理这种情况,从大量的网络连接中找出来真正需 要服务的Client。这正是NIO诞生的原因:提供一种Poll的模式,在所有的Client中找到 需要服务的Client。

回到我们刚刚说到的3个最最重要的Class:java.nio.channels中Selector和Channel ,以及java.nio中的Buffer。

Channel 代表一个可以被用于Poll操作的对象(可以是文件流也可以使网络流), Channel能够被注册到一个Selector中。通过调用Selector的 select方法可以从所有的 Channel中找到需要服务的实例(Accept,read ..)。Buffer对象提供读写数据的缓存。 相对于我们熟悉的Stream对象,Buffer提供更好的性能以及更好的编程透明性(人为控制 缓存的大小以及具体的操作)。

配合Buffer使用Channel

与传统模式的编程不用,Channel不使用Stream,而是Buffer。我们来实现一个简单的 非阻塞Echo Client:

package com.cnblogs.gpcuster;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class TCPEchoClientNonblocking {
  public static void main(String args[]) throws Exception {
   if ((args.length < 2) || (args.length > 3))//  Testforcorrect#ofargs
    throw new IllegalArgumentException(
      "Parameter(s): <Server> <Word> [<Port>]");
   String server = args[0];// ServernameorIPaddress
   // ConvertinputStringtobytesusingthedefaultcharset
   byte[] argument = args[1].getBytes();
   int servPort = (args.length == 3) ? Integer.parseInt(args[2]) :  7;
   // Createchannelandsettononblocking
   SocketChannel clntChan = SocketChannel.open();
   clntChan.configureBlocking(false);
   // Initiateconnectiontoserverandrepeatedlypolluntilcomplete
   if (!clntChan.connect(new InetSocketAddress(server, servPort)))  {
    while (!clntChan.finishConnect()) {
     System.out.print(".");// Dosomethingelse
    }
   }
   ByteBuffer writeBuf = ByteBuffer.wrap(argument);
   ByteBuffer readBuf = ByteBuffer.allocate(argument.length);
   int totalBytesRcvd = 0;// Totalbytesreceivedsofar
   int bytesRcvd;// Bytesreceivedinlastread
   while (totalBytesRcvd < argument.length) {
    if (writeBuf.hasRemaining()) {
     clntChan.write(writeBuf);
    }
    if ((bytesRcvd = clntChan.read(readBuf)) == -1) {
     throw new SocketException("Connection closed prematurely");
    }
    totalBytesRcvd += bytesRcvd;
    System.out.print(".");// Dosomethingelse
   }
   System.out.println("Received:" + //  converttoStringperdefaultcharset
     new String(readBuf.array(), 0, totalBytesRcvd));
   clntChan.close();
  }
}

时间: 2025-01-01 20:29:20

在Java中使用NIO进行网络编程的相关文章

windows系统中基于WIFI的网络编程

问题描述 windows系统中基于WIFI的网络编程 想用C++写一个在windows系统中基于WIFI传输数据的网络小程序,请各位高手指点一下,应该从哪方面入手,开发流程是什么样的? 解决方案 什么也不用操心,wifi对于你的程序来说,是透明的,换一句话说,无线有线你的代码无需变化.在windows下,可以使用winsock编程实现通讯,如果是vc++,用mfc,可以用csocket类,具体google下,有现成的代码例子. 解决方案二: 就是winsock2而已不管网络是什么,用这个就对了,

Java中的functor实现_Java编程

文章来源:csdn 作者:wangfengsdu 经常听到回调函数(callback function)这个概念, 所谓回调函数,就是指这个函数先在某处注册,而它将在稍后某个需要的时候被调用.比如在利用SDK 进行Windows编程的时候,我们需要注册一个WNDCLASS类,这个类中有这样一个参数 lpfnWndProc, 要进行消息处理,我们就要用处理消息的函数的指针给它赋值.消息处理函数什么时候被调用的?我们没有显式地在程序中看到啊.是OS调用的.  这是SDK的试验方式,当然用的是过程式的

Java中关于XML的API_JSP编程

简单介绍一下Java关于xml的API,这样大家看到了缩写就知道是干什么的了.水平有限,多多包涵. 1.JAXP(Java API for XML Parsing) 2.JAXB(Java API for XML Binding) 3.JAXM(Java API for XML Messaging) 4.JAX-RPC(Java API for XML-RPC) 1.JAXP定义了在Java中使用DOM, SAX, XSLT的通用的接口.这样在你的程序中你只要使用这些通用的接口,当你需要改变具体

面向对象编程:Java中的抽象数据类型_Java编程

文章来源:互联网 作者:PaleSting/CSDN 在本文中,我们将考察Java中的数据类型,但是我们将介绍抽象数据类型(ADT)的概念.我们还将通过介绍Java Collections Framework(Java 集合架构)来学习Java定义的一些ADT. ADT 一个ADT是一个仅由保存的数据类型和可能在这个数据类型上进行的操作定义的.开发者们只能通过ADT的操作方法来访问ADT的属性,而且他们不会知道这个数据类型内部各种操作是如何实现的. 在Java中,我们常常使用一个接口来给出一个操

Java中的浮点数分析_Java编程

文章来源:csdn 作者:treeroot 浮点数分为单精度和双精度,Java中的单精度和双精度分别为float和double.你们知道float和double是怎么存储的吗? float占4个字节,double占8个字节,为了方便起见,这里就只讨论float类型. float其实和一个int型的大小是一样的,一共32位,第一位表示符号,2-9表示指数,后面23位表示小数部分.这里不多说,请参考:http://blog.csdn.net/treeroot/archive/2004/09/05/9

Java套接字(Socket)网络编程入门_java

网络应用模式主要有: 主机/终端模式:集中计算,集中管理: 客户机/服务器(Client/Server,简称C/S)模式:分布计算,分布管理: 浏览器/服务器模式:利用Internet跨平台. www(万维网)就是建立在客户机/服务器模式上,以HTML语言和HTTP协议为基础,能够提供各种Internet服务的信息浏览系统.网络信息放在主机的不同位置,www服务器利用超文本链路链接各项信息.www客户机(浏览器Brower)负责与服务器建立联系,向服务器发送请求,处理HTML超媒体,提供图形用户

Java中基于Aspectwerkz的AOP_JSP编程

    一.AOP编程概览 面向对象编程技术进入软件开发的主流对软件的开发方式产生了极大的影响,开发者可以用一组实体以及这些实体之间的关系将系统形象地表示出来,这使得他们能够设计出规模更大.更复杂的系统,开发周期也比以前更短.OO开发的唯一问题是,它本质上是静态的,需求的细微变化就可能对开发进度造成重大影响. Aspect-Oriented Programming(AOP)是对OO技术的补充和完善,它允许开发者动态地修改静态的OO模型,构造出一个能够不断增长以满足新增需求的系统,就象现实世界中的

Java中的面向对象(object oriented)编程简介

程序包含两部分组成: 数据 和操作数据的函数; 面向过程的设计方法是自顶向下的功能分解, 把一个需求分解成多个子功能, 开发子功能并进行单元测试, 在组装成一个完整的应用程序; 问题: 1. 程序主要关注功能, 其次数据, 数据从一个函数流动至另一个函数; 2. 数据结构需要贯穿多个函数; 3. 修改数据结构, 会在程序中造成连锁反应; 4. 数据完整性错误, 可能发生在多个函数, 出现bug, 不容易查找; 面向对象的设计方法是 设计对象, 主要改进: 1. 主要关注数据结构, 其次才是功能;

了解一下JAVA中的NIO模块

网上资料大把,但要写写代码,我这个年纪的人才有一点点记忆了.. 参考URL: http://blog.csdn.net/wuxianglong/article/details/6612282 package com.cg.io; import java.io.*; import java.nio.*; import java.nio.channels.*; public class TestIntBuffer { static private final byte message[] = {83