- 浏览: 876676 次
- 性别:
- 来自: 美国图森
最新评论
-
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 11468现在上一点规模的 ... -
Spring freemarker页面乱码解决
2011-01-13 11:56 7585在开发过程中遇到乱码十分的头痛,如果你在开发过程中也遇 ... -
数据漂白算法研究
2010-12-07 18:05 3835你的手机是不是 ... -
理解使用static import 机制
2010-11-09 08:48 3240J2SE 1.5里引入了“Sta ... -
理解多线程设计模式
2010-11-08 17:43 10554多线程设计模式:1.Single Threaded Execu ... -
理解ThreadLocal
2010-11-03 17:04 1971ThreadLocal是什么 早在JDK 1 ... -
经验总结:高性能的数据同步
2010-11-03 10:03 6459最近在做一个银行的生产数据脱敏系统,今天写代码时遇到 ... -
用JSSE实现网络安全通信
2010-06-25 15:11 3903在网络上信息由源主机到目标主机要经过很多路由和计算机, ... -
Java实时监控日志文件并输出
2010-06-19 17:21 61354最近有一个银行数据漂白系统,要求操作人员在页面调用远端 ... -
Junit测试private方法
2010-04-28 14:09 8086package com.bill99.junit; pu ... -
保护眼睛的豆沙色
2010-03-19 09:46 3604作我们IT这行的,一天要盯着电脑看,时间长了眼睛会感觉发酸 ... -
中国联通短信网关接入程序源代码(SGIP1.2协议)
2010-01-11 12:23 43377自从我发了博文“中国联通SP业务开发总结”后有很多的朋友问 ... -
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
2009-12-24 13:14 67582原地址:http://topic.csdn.net/t/200 ... -
处理线程泄露
2009-12-01 15:10 8633当一个单线程化 ... -
在Timer和ScheduledExecutorService间决择
2009-11-27 10:25 13434java.util.Timer计时器有管理任务延迟执行(& ... -
Socket通信模式:收发线程互斥
2009-11-14 19:09 8796有做过通信程序或着短信接入程序的程序员都知道,与之 ... -
ASCII码对照表
2009-11-12 11:26 2616ASCII表 ASCII值 控制字符 ASC ... -
java.net.SocketException: Software caused connection abort: recv failed 异常分析
2009-11-12 11:01 15856java.net.SocketException: Softw ... -
用State模式减少if..elseif语句
2009-11-03 17:20 7135我们在写程序的过 ... -
HttpURLConnection设置网络超时
2009-10-29 17:30 9515Java中可以使用HttpURLConnection来请 ...
相关推荐
阻塞通信和非阻塞通信的区别 阻塞通信和非阻塞通信是两种不同的通信模式,主要应用于Socket通信中。在Java中,通过使用java.nio包中的类可以实现非阻塞通信。 阻塞通信是指在发送或接收数据时,当前线程将被阻塞,...
### 阻塞通信与非阻塞通信:深入解析与应用 #### 1. 概述 在并行计算领域,尤其是使用MPI(Message Passing Interface)进行编程时,通信模式的选择对于程序性能至关重要。阻塞通信与非阻塞通信是两种基本的通信方式...
Java非阻塞通信是现代Java开发中的一个重要概念,特别是在高并发和高性能的系统设计中。非阻塞通信允许程序在等待数据就绪时不会被挂起,而是继续执行其他任务,提高了系统的整体效率。这种技术主要应用于网络I/O...
用Java实现非阻塞通信 java.nio包提供了支持非阻塞通信的类,主要包括: ● ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信。 ● SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信...
### 基于Java NIO的非阻塞通信的研究与实现 #### 摘要 本文探讨了Java NIO(New I/O)框架中的非阻塞通信机制,并对其原理及应用进行了深入研究。NIO是一种现代I/O处理方法,通过引入缓冲区、通道和选择器等新概念...
非阻塞通信模式下,当调用 socket 的读写操作时,如果数据未准备好,系统不会挂起线程,而是立即返回一个错误,允许线程继续执行其他任务。这种方式提高了并发性能,因为多个任务可以在单个线程中并行处理。 ### 3....
阻塞与非阻塞通信是计算机网络编程中的两种基本通信方式,主要涉及到Java NIO(Non-blocking Input/Output,非阻塞输入/输出)框架。Java NIO 提供了一种新的方式来处理I/O操作,使得程序在进行读写操作时,不再必须...
非阻塞通信是一种高效、灵活的网络编程方式,它与传统的阻塞通信模式不同,能够显著提高系统的并发处理能力。在Java中,非阻塞通信主要通过NIO(Non-blocking Input/Output,非阻塞输入/输出)实现,这是一种基于...
为此,Java非阻塞通信技术应运而生,它基于Java NIO(New I/O)包的全新设计理念,为服务端的高并发处理提供了新的解决方案。 Java NIO的非阻塞通信机制,与传统阻塞式通信的最大区别在于它采用了事件驱动的方式...
通过java网络编程深入理解socket阻塞通信和非阻塞通信的在网络中的应用 源码包每一行都有注释,在代码里面每一个类都有详细的注释来解释这个类的功能这个方法的功能,调用哪一个类的哪一个功能等等。 压缩包包含实验...
利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信。 首先,先了解下SocketServer模块中可供使用的类: BaseServer:包含服务器的核心功能与混合(mix-in)类挂钩;这个类只用于派生,所以不会生成这...
接下来是`EchoClient.java`,客户端通常采用单线程阻塞I/O模型,但在NIO模式下,也可以实现非阻塞通信。客户端创建一个`SocketChannel`连接到服务器,然后同样注册到`Selector`,设置感兴趣的读事件。客户端发送数据...
ePump - 一个事件驱动的多线程 c 框架英文自述文件基于I/O事件通知、非阻塞通信和多线程事件驱动模型的C语言框架帮助您开发高性能、大量并发连接的服务器。ePump是一个基于I/O事件通知、非阻塞通信、多路复用、多...
ePump是一个基于IO事件通知、非阻塞通信、多路复用、多线
1、C++SOCKET同步阻塞、异步非阻塞通信服务端、客户端代码,支持多个客户端连接。 2、断线重连(服务端或客户端没有启动顺序要求,先开启的等待另一端连接); 3、服务端支持同时连接多个客户端; 4、阅读代码就...
然而,非阻塞通信引入了复杂性,需要管理异步通信的状态,并确保正确完成(通过调用`MPI_Wait`或`MPI_Test`)。 3. **非阻塞通信的完成和同步** 在使用`MPI_Isend`后,发送进程需要确认消息是否已经被接收。这通常...
在Java中实现非阻塞通信,主要依赖于Java NIO(Non-blocking Input/Output)库。 1. Java NIO简介: Java NIO是Java 1.4引入的新I/O API,是对传统BIO(Blocking I/O)模型的补充。NIO的核心概念包括通道(Channel...
- **非阻塞模式**:通过`java.nio`提供的非阻塞通信机制,服务器可以使用少量的线程处理大量的客户端连接,极大地提高了系统吞吐量和响应速度。使用`Selector`监听多个`Channel`的事件,避免了线程阻塞,减少了线程...