Loading
新闻中心库存中心价格中心PDF中心图片中心
ICGLE 电子技术支持中心,为电气人员和相关企业提供全面的信息(IC技术\IC库存\IC图片\PDF资料等)服务
总线设计PCB设计单片机DSPARM
JAVA驱动设计C/C++汇编J2EE网络协议中间件技术嵌入式系统无线通信通信网络模拟技术接口电路显示光电传感与控制EDA/PLD
气流体控制电子产品电机及工具通信设备仪器仪表电线电缆建筑电气低压电器高压电器电源工控自动化广电设备医疗器械More..
电源设计仪器仪表技术专递电路图片电子专栏储存技术汽车电子测量测试音响技术家用电器
成功方案市场分析行业标准应用前沿芯片应用综合专区
使用Java NIO提高服务端程序的性能
来源:java.chinaitlab.com   作者:
字体大小:[大][中][小]


  结合具体的Java Socket编程,讨论使用NIO提高服务端程序的性能的问题。

  Java NIO增加了新的SocketChannel、ServerSocketChannel等类来提供对构建高性能的服务端程序的支持。 SocketChannel、ServerSocketChannel能够在非阻塞的模式下工作,它们都是selectable的类。在构建服务器或者中间件时,推荐使用Java NIO。

  在传统的网络编程中,我们通常使用一个专用线程(Thread)来处理一个Socket连接,通过使用NIO,一个或者很少几个Socket线程就可以处理成千上万个活动的Socket连接。

  通常情况下,通过ServerSocketChannel.open()获得一个ServerSocketChannel的实例,通过SocketChannel.open或者serverSocketChannel.accept()获得一个SocketChannel实例。要使ServerSocketChannel或者SocketChannel在非阻塞的模式下操作,可以调用

serverSocketChannel.configureBlocking (false);

或者

socketChannel.configureBlocking (false);

语句来达到目的。通常情况下,服务端可以使用非阻塞的ServerSocketChannel,这样,服务端的程序就可以更容易地同时处理多个socket线程。

  下面我们来看一个综合例子,这个例子使用了ServerSocketChannel、SocketChannel开发了一个非阻塞的、能处理多线程的Echo服务端程序,见示例12-14。

【程序源代码】

1 // ==================== Program Discription =====================
2 // 程序名称:示例12-14 : SocketChannelDemo.java
3 // 程序目的:学习Java NIO#SocketChannel
4 // ==============================================================
5
6
7 import java.nio.ByteBuffer;
8 import java.nio.channels.ServerSocketChannel;
9 import java.nio.channels.SocketChannel;
10 import java.nio.channels.Selector;
11 import java.nio.channels.SelectionKey;
12 import java.nio.channels.SelectableChannel;
13
14 import java.net.Socket;
15 import java.net.ServerSocket;
16 import java.net.InetSocketAddress;
17 import java.util.Iterator;
18
19 public class SocketChannelDemo

20
21 {
22 public static int PORT_NUMBER = 23;//监听端口
23 ServerSocketChannel serverChannel;
24 ServerSocket serverSocket ;
25 Selector selector ;
26 private ByteBuffer buffer = ByteBuffer.allocateDirect (1024);
27
28 public static void main (String [] args)
29 throws Exception
30 {
31 SocketChannelDemo server=new SocketChannelDemo();
32 server.init(args);
33 server.startWork();
34 }
35
36
37 public void init (String [] argv)throws Exception
38 {
39 int port = PORT_NUMBER;
40
41 if (argv.length > 0) {
42 port = Integer.parseInt (argv [0]);
43 }
44
45 System.out.println ("Listening on port " + port);
46
47 // 分配一个ServerSocketChannel
48 serverChannel = ServerSocketChannel.open();
49 // 从ServerSocketChannel里获得一个对应的Socket
50 serverSocket = serverChannel.socket();
51 // 生成一个Selector
52 selector = Selector.open();
53
54 // 把Socket绑定到端口上
55 serverSocket.bind (new InetSocketAddress (port));
56 //serverChannel为非bolck
57 serverChannel.configureBlocking (false);
58
59 // 通过Selector注册ServerSocetChannel
60 serverChannel.register (selector, SelectionKey.OP_ACCEPT);
61
62 }
63
64 public void startWork()throws Exception

65
66 {
67 while (true) {
68
69 int n = selector.select();//获得IO准备就绪的channel数量
70
71 if (n == 0) {
72 continue; // 没有channel准备就绪,继续执行
73 }
74
75 // 用一个iterator返回Selector的selectedkeys
76 Iterator it = selector.selectedKeys().iterator();
77
78 // 处理每一个SelectionKey
79 while (it.hasNext()) {
80 SelectionKey key = (SelectionKey) it.next();
81
82 // 判断是否有新的连接到达
83 if (key.isAcceptable()) {
84           //返回SelectionKey的ServerSocketChannel
85 ServerSocketChannel server =
(ServerSocketChannel) key.channel();
86 SocketChannel channel = server.accept();
87
88 registerChannel (selector, channel,
89 SelectionKey.OP_READ);
90
91 doWork (channel);
92 }
93
94 // 判断是否有数据在此channel里需要读取
95 if (key.isReadable()) {
96
97 processData (key);
98
99 }
100
101 //删除 selectedkeys
102 it.remove();
103 }
104 }
105 }
106 protected void registerChannel (Selector selector,
107 SelectableChannel channel, int ops)
108 throws Exception
109 {

110 if (channel == null) {
111 return;
112 }
113
114
115 channel.configureBlocking (false);
116
117 channel.register (selector, ops);
118 }
119
120 //处理接收的数据
121 protected void processData (SelectionKey key)
122 throws Exception
123 {
124
125
126 SocketChannel socketChannel = (SocketChannel) key.channel();
127 int count;
128
129 buffer.clear(); // 清空buffer
130
131 // 读取所有的数据
132 while ((count = socketChannel.read (buffer)) > 0) {
133 buffer.flip();
134
135 // send the data, don′t assume it goes all at once
136 while (buffer.hasRemaining())
137 {
138 //如果收到回车键,则在返回的字符前增加[echo]$字样
139 if(buffer.get()==(char)13)
140 {
141 buffer.clear();
142 buffer.put("[echo]___FCKpd___0quot;.getBytes());
143 buffer.flip();
144
145 }
146 socketChannel.write (buffer);//在Socket里写数据
147 }
148
149 buffer.clear(); // 清空buffer
150 }
151
152 if (count < 0) {
153 // count<0,说明已经读取完毕
154 socketChannel.close();

155 }
156 }
157
158
159 private void doWork (SocketChannel channel)throws Exception
160 {
161 buffer.clear();
162 buffer.put ("
Hello,I am working,please input some thing,and i will echo to you!
[echo]
___FCKpd___0quot;.getBytes());
163 buffer.flip();
164 channel.write (buffer);
165 }
166
167 }

使用:运行此程序,然后在控制台输入命令telnet localhost 23。
Upload by 小刘(2007-6-4)
IC
IC
推荐技术文章:
·基于C语言的设计流优化语音识别芯片结....
·针对嵌入式SoC应用的C编程优化..
·如何用C语言开发DSP嵌入式系统..
·浅析malloc()的几种实现方式..
·用Eclipse+MyEclipse....
·Java中使用接口实现多继承和多态的....
·提升JSP中页面响应速度的七大秘籍绝....
·Static和Final修饰类属性变....
·探讨JAR文件无限可能性..
·Tomcat集群与负载均衡..
·java虚拟机管理大内存..
·java中使用MD5加密算法进行加密..
·EMF模型解析的策略分析..
·编写对GC友好,又不泄漏的代码..
·J2SE5.0新特性之windows....
·java中通过xpath处理含有命名....
·使用Hashtable对字符串进行碰....
·揭开 Java 安全标准的神秘面纱 ..
·java的线程安全四种方式五个等级..
·破除java神话之原子操作都是线程安....
·Java服务器端编程安全必读
·编写高效的线程安全类
·用Java向Web站点发送POST请..
·Java多线程的优先级
·基于Java的嵌入式网络视频服务器
·Java源码分析:深入探讨Itera..
·在Java里面调用CUI程序的方法
·从C++到Java--理解面向对象是..
·避免JavaEE项目评估中的常见错误
·XML和Java:一个强大的组合
·J2ME平台下基于手机定位实现的移动..
·Java回归嵌入式无线通信
·用Java实现FTP服务器
·在VxWorks下实现NAT/NAP..
·VxWorks中的地址映射
·基于Rhapsody和VxWorks..
·VxWorks中怎么从Flash B..
·基于嵌入式操作系统VxWorks的S..
·基于VxWorks的bootrom代..
·VxWorks for X86的输入..
IC
IC

©2007 版权归ICGLE所有   页面执行时间:93.750毫秒