JavaNIO非阻塞模式

package com.java.NIO;

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.util.Date;
import java.util.Iterator;
import java.util.Scanner;

import org.junit.Test;

/**
 *
 * @author fliay
 *
 *	一、使用NIO 完成网络通信的三个核心
 *	1.通道(channel):负责链接
 *		java.nio.channels.Channel 接口
 *			|--SelecttableChannel
 *				|--SocketChannel
 *				|--serverSocketChannel
 *				|--DatagramChannel
 *
 *				|--Pipe.SinkChannel
 *				|--Pipe.SourceChannel
 *	2.缓冲区(Buffer):负责数据的存取
 *
 *	3.寻则其(Selector): 是SelectableChannel的多路复用器,用于监控SelectableChannel的IO状况
 *
 *
 */
public class TestNoBlockingNIO {

	@Test//客户端
	public void client() throws IOException{
		//1.获取通道
		SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 1008));

		//2.切换非阻塞模式
		sChannel.configureBlocking(false);

		//3.分配指定大小的缓冲区
		ByteBuffer buf = ByteBuffer.allocate(1024);

		//4.发送数据给服务器
		Scanner input = new Scanner(System.in);

		while(input.hasNext()){
			String str = input.nextLine();
			buf.put((new Date().toString()+":\n"+str).getBytes());
			buf.flip();
			sChannel.write(buf);
			buf.clear();
		}

		//5.关闭通道
		sChannel.close();

	}

	@Test //服务器
	public void Server() throws IOException{
		//1.获取通道
		ServerSocketChannel ssChannel = ServerSocketChannel.open();

		//2.切换非阻塞模式
		ssChannel.configureBlocking(false);

		//3.绑定连接
		ssChannel.bind(new InetSocketAddress(1008));

		//4.获取选择器
		Selector selector = Selector.open();

		//5.将通道注册到选择器上,并且指定“监听接收事件”
		ssChannel.register(selector, SelectionKey.OP_ACCEPT);

		//6.轮训式的获获取选择器上的以及“准备就绪”的事件
		while(selector.select()>0){
			//7.获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
			Iterator<SelectionKey> it = selector.selectedKeys().iterator();
			while(it.hasNext()){
				//8.获取就绪的事件
				SelectionKey sk = it.next();
				//9.判断具体是什么事件准备就绪
				if(sk.isAcceptable()){
					//10. 若“接受就绪” ,获取客户链接
					SocketChannel sChannel = ssChannel.accept();
					//11. 切换非阻塞模式
					sChannel.configureBlocking(false);
					//12. 将该通道注册到选择器上
					sChannel.register(selector, SelectionKey.OP_READ);
				}else if(sk.isReadable()){
					//13. 获取当前选择器上“读就绪”状态的通道
					SocketChannel sChannel = (SocketChannel) sk.channel();

					//14. 读取数据
					ByteBuffer buf= ByteBuffer.allocate(1024);

					int len =0;
					while((len =sChannel.read(buf))>0){
						buf.flip();
						System.out.println(new String(buf.array(),0,len));
						buf.clear();
					}

				}
				//15. 取消选择键 SelectionKey
				it.remove();
			}

		}
	}

}

  

时间: 2024-08-28 23:10:15

JavaNIO非阻塞模式的相关文章

非阻塞模式(ioctlsocket)

1 //Server.cpp 2 #include <stdio.h> 3 #include <winsock2.h> //winsock.h (2种套接字版本) 4 #pragma comment(lib,"ws2_32.lib") //wsock32.lib 5 6 #define MAXSIZE 100 // 7 8 int main() 9 { 10 // 11 int retVal; 12 13 char buf[MAXSIZE]; 14 15 //初

深入 CSocket 编程之阻塞和非阻塞模式

有时,花上几个小时阅读.调试.跟踪优秀的源码程序,能够更快地掌握某些技术关键点和精髓.当然,前提是对这些技术大致上有一个了解. 我通过几个采用 CSocket 类编写并基于 Client/Server (客户端 / 服务端)的网络聊天和传输文件的程序 ( 详见: 源代码参考 ) ,在调试这些程序的过程中,追踪深入至 CSocket 类核心源码 Sockcore.cpp , 对于CSocket 类的运行机制可谓是一览无遗,并且对于阻塞和非阻塞方式下的 socket 程序的编写也是稍有体会. 阅读本

非阻塞模式下connect 成功失败判断

将一个socket 设置成阻塞模式和非阻塞模式,使用fcntl方法,即: 设置成非阻塞模式: 先用fcntl的F_GETFL获取flags,用F_SETFL设置flags|O_NONBLOCK; 即: flags = fcntl(sockfd, F_GETFL, 0);                        //获取文件的flags值. fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);   //设置成非阻塞模式: 同时在接收和发送数据时,需要使用MS

PHP非阻塞模式

PHP非阻塞模式 by 尘缘 on 七月 31st, 2014 // Filed Under → php 让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施: 一.若你使用的是FastCGI模式,使用fastcgi_finish_request()能马上结束会话,但PHP线程继续在跑. 帮助 01 02 03 04 05 06 07 08 09 10 echo"program start."; file_put_c

delphi Winsock非阻塞模式详解

delphi Winsock非阻塞模式详解   Winsockt的TClientSocket设置ClientType的属性为ctNonBlocking.则通讯模式为非阻塞模式. ctBlocking为阻塞模式,这里说一下阻塞与非阻塞的一些区别. ctBlocking模式当客户端请求数据后,线程阻塞不继续执行,直到服务端返回数据,客户端将据需执行,并读取数据. 然而阻塞模式的缺陷还是比较大的,经常会使程序死掉或者假死.当服务端发送较大的文件时,阻塞模式基本废掉了,由于数据缓冲较小,不能及时的获取数

PHP非阻塞模式 (转自 尘缘)

让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施: 一.若你使用的是FastCGI模式,使用fastcgi_finish_request()能马上结束会话,但PHP线程继续在跑. 帮助 01 02 03 04 05 06 07 08 09 10 echo "program start."; file_put_contents('log.txt','start-time:'.date('Y-m-d H:i:s'),

看到关于socket非阻塞模式设置方式记录一下。

关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的:我打个很简单的比方,如果你调用socket send函数时: 如果是阻塞模式下: send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR:如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么

转:PHP非阻塞模式

你可以任意转摘“PHP非阻塞模式”,但请保留本文出处和版权信息.作者:尘缘,QQ:130775,来源:http://www.4wei.cn/archives/1002336 让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施: 一.若你使用的是FastCGI模式,使用fastcgi_finish_request()能马上结束会话,但PHP线程继续在跑. 帮助 01 02 03 04 05 06 07 08 09 10 ech

转:PHP中实现非阻塞模式

原文来自于:http://blog.csdn.net/linvo/article/details/5466046 程序非阻塞模式,这里也可以理解成并发.而并发又暂且可以分为网络请求并发 和本地并发 . 先说一下网络请求并发 理论描述 假设有一个client,程序逻辑是要请求三个不同的server,处理各自的响应.传统模型当然是顺序执行,先发送第一个请求,等待收到响应数据后再发送第二个请求,以此类推.就像是单核CPU,一次只能处理一件事,其他事情被暂时阻塞.而并发模式可以让三个server同时处理