- 浏览: 869654 次
- 性别:
- 来自: 美国图森
最新评论
-
jnjeC:
jake_12345 写道大哥,这写错了吧Class.isAs ...
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别 -
lgh1992314:
https://my.oschina.net/xianggao ...
Servlet生命周期 -
qq412796770:
大哥,百度第一条就是你的,好歹也修改一下吧
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别 -
技术无涯苦作舟:
大哥,百度第一条就是你的,好歹也修改一下吧
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别 -
lgh1992314:
大哥,百度第一条就是你的,好歹也修改一下吧
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
对于用ServerSocket和Socket写的服务器程序或着客户端程序,在运行的时候常常会阻塞,如当一个线程执行ServerSocket的accept()方法,如果没有客户机连接,该线程就会一直阻塞直到有了客户机连接才从accept()方法返回,再如,当线程执行Socket的read()方法,如果输入流中没有数据,该线程就会一直等到有数据可读时才从read()方法返回。
如果服务器要与多个客户机通信,通常做法为每个客户机连接开启一个服务线程,每个工作线程都有可能经常处于长时间的阻塞状态。
从JDK1.4版本开始,引入了非阻塞的通信机制。服务器程序接收客户连接、客户程序建立与服务器的连接,以及服务器程序和客户程序收发数据的操作都可以按非阻塞的方式进行。服务器程序只需要创建一个线程,就能完成同时与多个客户通信的任务。
非阻塞通信要比传统的阻塞方式效率要高,Apache的MIMA框架就是以java.nio包中的类编写的。
不知道是否有朋友看过 孙卫琴写的《Java网络编程精解》,在提到线程阻塞的时
我对描红的描述持不同的意见 byte[] msgBytes = new byte[512]; 如果按书中描述,这行代码必须读到512个字节后才从阻塞状态中返回,如果没有读到足够的512个字节,则一直阻塞。但实际情况却不是这样的,只要流里哪怕只有一个字节 ,inputStream.read(msgBytes)也会立即返回,返回值为读到的字节数。 下面是简单的NIO示例 1、服务端程序,非阻塞方式 2、客户端程序,阻塞方式 总体而信,阻塞模式和非阻塞模式都可以同时处理多个客户机的连接,但阻塞模式需要较多的线程许多时间都浪费在阻塞I/O操作上,Java虚拟机需要频繁地转让CPU的使用权,而非阻塞模式只需要少量线程即可完成所有任务,非阻塞模式能更有效的利用CPU,系统开销小,能够提高程序的并发性能。
int read():只要输入有一个字节,就算足够。
int read(byte[] buff):只要输入流中的字节数目与参数buff数组的长度相同,就算足够。
inputStream.read(msgBytes); package com.bill99.nioserver;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.charset.Charset;
import java.util.Iterator;
public class NIOServer {
private Selector socketSelector = null;
private ServerSocketChannel ssChannel = null;
private SocketChannel socketChannel =null;
private static SelectionKey key = null;
private int port =5512;
private int backlog = 100;
private Charset charset = Charset.defaultCharset();
private ByteBuffer shareBuffer = ByteBuffer.allocate(1024);//生成1kb的缓冲区,可以根据实际情况调的更大些
public NIOServer() {
try {
socketSelector = SelectorProvider.provider().openSelector();
ssChannel =ServerSocketChannel.open() ;
ssChannel.socket().bind(new InetSocketAddress(port),100);
System.out.println(String.format("NIO服务器启动,监听端口%1$s,最大连接数%2$s", port,backlog));
} catch(IOException e){
throw new ExceptionInInitializerError(e);
}
}
/**
* 接收客户端连接
*/
public void acceptConnect() {
while(true) {
try {
SocketChannel socketChannel = ssChannel.accept();//阻塞模式,直到有连接进入
System.out.println("收到客户机连接,来自:"+ssChannel.socket().getInetAddress());
socketChannel.configureBlocking(false);//设置非阻塞模式
synchronized(this){
socketSelector.wakeup();
socketChannel.register(socketSelector,SelectionKey.OP_READ|
SelectionKey.OP_WRITE);
}
} catch(IOException e){e.printStackTrace();}
}
}
/**
* 读写服务
* @throws IOException
*/
public void service() throws IOException{
while (true) {
synchronized (this) {//空的同步块,目的是为了避免死锁
}
if (!(socketSelector.select() > 0)) {
continue;
}
Iterator<SelectionKey> it = socketSelector.selectedKeys().iterator();
while (it.hasNext()) {
key = it.next();
it.remove();
if(key.isReadable()) {// 读就绪
this.readDataFromSocket(key);
}
if(key.isWritable()){//写就绪
this.sayWelcome(key);
}
}
}
}
//读取客户机发来的数据
private void readDataFromSocket(SelectionKey key) throws IOException {
shareBuffer.clear();//清空buffer
socketChannel=(SocketChannel) key.channel();
int num=0;
while((num = socketChannel.read(shareBuffer))>0){
shareBuffer.flip();//将当前极限设置为位置,并把设置后的位置改为0
}
if(num ==-1){//读取流的未尾,对方已关闭流
socketChannel.close();
return;
}
System.out.println("client request:"+charset.decode(shareBuffer).toString());
}
//向客户机发响应信息
private void sayWelcome(SelectionKey key) throws IOException {
shareBuffer.clear();//清空buffer
socketChannel=(SocketChannel) key.channel();
shareBuffer.put("Welcome to china!this is a greate and very beautifual country!\n".getBytes());
shareBuffer.flip();//将当前极限设置为位置,并把设置后的位置改为0
socketChannel.write(shareBuffer);
}
//Main方法
public static void main(String[] args) {
final NIOServer server = new NIOServer();
Runnable task = new Runnable() {
public void run() {
server.acceptConnect();
}
};
new Thread(task).start();//启动处理客户机连接的线程
try {
server.service();
} catch (IOException e) {//发生IO流异常时,关闭对应的socket
try {
key.channel().close();
key.cancel();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
package com.bill99.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.CharBuffer;
import javax.net.SocketFactory;
//测试类
public class BlockingClient {
private Socket socket = null;
private OutputStream out = null;
private InputStream in = null;
public BlockingClient() {
try {
socket= SocketFactory.getDefault().createSocket("127.0.0.1", 5512);
out = socket.getOutputStream();
in = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
//发送请求并接收应答
public String receiveRespMsg(String reqMsg) throws IOException{
out.write(reqMsg.getBytes());
out.flush();
in = socket.getInputStream();
int c =0;
CharBuffer buffer = CharBuffer.allocate(1024);
while((c=in.read())!=-1 && c!=10){
buffer.put((char)c);
}
return new String(buffer.array()).trim();
}
public static void main(String[] args) throws Exception{
BlockingClient client = new BlockingClient();
System.out.println("服务器响应:"+client.receiveRespMsg("hello\n"));
}
}
发表评论
-
人在江湖:如何用代码保护自己
2011-10-12 16:30 11230现在上一点规模的 ... -
Spring freemarker页面乱码解决
2011-01-13 11:56 7479在开发过程中遇到乱码十分的头痛,如果你在开发过程中也遇 ... -
数据漂白算法研究
2010-12-07 18:05 3765你的手机是不是 ... -
理解使用static import 机制
2010-11-09 08:48 3182J2SE 1.5里引入了“Sta ... -
理解多线程设计模式
2010-11-08 17:43 10422多线程设计模式:1.Single Threaded Execu ... -
理解ThreadLocal
2010-11-03 17:04 1913ThreadLocal是什么 早在JDK 1 ... -
经验总结:高性能的数据同步
2010-11-03 10:03 6404最近在做一个银行的生产数据脱敏系统,今天写代码时遇到 ... -
用JSSE实现网络安全通信
2010-06-25 15:11 3821在网络上信息由源主机到目标主机要经过很多路由和计算机, ... -
Java实时监控日志文件并输出
2010-06-19 17:21 61123最近有一个银行数据漂白系统,要求操作人员在页面调用远端 ... -
Junit测试private方法
2010-04-28 14:09 8010package com.bill99.junit; pu ... -
保护眼睛的豆沙色
2010-03-19 09:46 3559作我们IT这行的,一天要盯着电脑看,时间长了眼睛会感觉发酸 ... -
中国联通短信网关接入程序源代码(SGIP1.2协议)
2010-01-11 12:23 42850自从我发了博文“中国联通SP业务开发总结”后有很多的朋友问 ... -
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
2009-12-24 13:14 67450原地址:http://topic.csdn.net/t/200 ... -
处理线程泄露
2009-12-01 15:10 8563当一个单线程化 ... -
在Timer和ScheduledExecutorService间决择
2009-11-27 10:25 13372java.util.Timer计时器有管理任务延迟执行(& ... -
Socket通信模式:收发线程互斥
2009-11-14 19:09 8724有做过通信程序或着短信接入程序的程序员都知道,与之 ... -
ASCII码对照表
2009-11-12 11:26 2518ASCII表 ASCII值 控制字符 ASC ... -
java.net.SocketException: Software caused connection abort: recv failed 异常分析
2009-11-12 11:01 15678java.net.SocketException: Softw ... -
用State模式减少if..elseif语句
2009-11-03 17:20 7072我们在写程序的过 ... -
HttpURLConnection设置网络超时
2009-10-29 17:30 9468Java中可以使用HttpURLConnection来请 ...
相关推荐
MPI编程的阻塞通信和非阻塞通信的区别,如何使用!
java非阻塞通信研究,研究java的非阻塞通信
关于socket通信原理的解释,详细的解释了阻塞通信和非阻塞通信的区别
用Java实现非阻塞通信 java.nio包提供了支持非阻塞通信的类,主要包括: ● ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信。 ● SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信...
基于WSAAsyncSelect非阻塞通信程序设计
自己的学习阻塞及非阻塞通信的笔记
通过java网络编程深入理解socket阻塞通信和非阻塞通信的在网络中的应用 源码包每一行都有注释,在代码里面每一个类都有详细的注释来解释这个类的功能这个方法的功能,调用哪一个类的哪一个功能等等。 压缩包包含实验...
基于JavaNIO的非阻塞通信的研究与实现
利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信。 首先,先了解下SocketServer模块中可供使用的类: BaseServer:包含服务器的核心功能与混合(mix-in)类挂钩;这个类只用于派生,所以不会生成这...
关于非阻塞通信例子【nonblocking】示例,可以学学,很有用的,用nio协议。底层走socket通信。
JAVA非阻塞通信技术原理研究与实现
非阻塞TCP通信模式,给新手做个参考。源代码均已通过编译。
非阻塞 udp server,适合udp非阻塞通信
C++串口通信类。 可以方便的进行串口通信,如果需要用串口可以试用一下哈。包括阻塞与非阻塞方法。
使用MFC实现非阻塞套接字通信,可以多个客户端和一个服务器任意通信,通信协议采用protobuf,代码可直接运行exe文件,平台为vs2013。
java,java网络,java阻塞编程,非阻塞与阻塞编程
NULL 博文链接:https://1358440610-qq-com.iteye.com/blog/2117280
近年来,由于频率墙和功耗墙的存在,计算机计算性能的提升主要依赖于计算核心数量的增加,这使得传统的串行算法设计逐步转向基于多核和众核的并行算法设计,越多越多的应用领域,特别是人工智能领域需要并行数据结构...
采用UDP方式的进程间通信模型,支持非阻塞,socket编程,采用select网络模型。 采用UDP方式的进程间通信模型,支持非阻塞,socket编程,采用select网络模型。 采用UDP方式的进程间通信模型,支持非阻塞,socket编程...