`
kree
  • 浏览: 129244 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

非阻塞式Socket举例

阅读更多
package NonBlockingSocket;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;

public class Server {// 这是服务端

	/**
	 * @param args
	 * @throws IOException
	 * 
	 * 非阻塞的Socked使用总结(服务器端): 一、涉及关键类: 1、ByteBuffer 2、SelectionKey 3、Selector
	 * 4、ServerSocketChannel 5、Iterator 6、SocketChannel 二、各类的综合使用方法及相互联系
	 * 以下是使用前对各对象的设置: 1、得到ServerSocketChannel和Selector对象
	 * 2、设置ServerSocketChannel内部channel阻塞方式 3、把ServerSocketChannel绑定到指定地址的指定端口上
	 * 4、把ServerSocketChannel注册给Selector对象,并选择感兴趣的动作 以下是使用过程:
	 * 1、使用Selector对象对指定地址指定端口的请求进行选择,这里的选择只关注自己以前设置的感兴趣的请求
	 * 2、从Selector对象里得到感兴趣的链接的Set,然后得到该Set对象的迭代器Iterator对象
	 * 3、如果该迭代器里有元素,则依次使用next()取出,取出的元素可强转为SelectionKey,此SelectionKey对象至少包装了两个属性:一个是该属性是哪种类型的,另一个是一个SelectableChannel
	 * 如果此SelectedKey是OP_ACCEPT,那么SelectableChannel可以强转为ServerSocketChannel对象,使这个对象accept()可以得到SocketChannel对象,同样可以像注册ServerSocketChannel
	 * 一样注册SocketChannel到Selector对像并选择自己感兴趣的动作。SelectionKey的isConnecttable()方法不适用于服务端。
	 * 4、可以从SocketChannel内read()和write()信息,这些信息必须包装在ByteBuffer内
	 * 5、可以对ByteBuffer里的内容做多种解释,其中一种是人类比较容易理解的字符格式:CharBuffer,转换方式有两种:一种是ByteBuffer.asCharBuffer()这种转换只是改变了相同内容的不同解释;
	 * 另一种是使用编码: Charset tCs=Charset.forName("gb2312"); CharBuffer
	 * tCb=tCs.newDecoder().decode(tBb); 这种转换是对相同语义做不同存储。
	 * 6、经常将上述步骤放在一个大的循环内部,这样可以不断地检查指定地址的指定端口的请求
	 */
	private final static int BUF_SIZE = 1024;

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		Server s = new Server();
		s.startServer();
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	//
	public Server() {
		// TODO Auto-generated constructor stub
		init();
	}

	ServerSocketChannel ssc;
	Selector sel;
	boolean start;

	//
	private void init() {
		// TODO Auto-generated method stub
		try {
			ssc = ServerSocketChannel.open();
			ssc.socket()
					.bind(
							new InetSocketAddress(InetAddress
									.getByAddress(new byte[] { (byte) 11,
											(byte) 11, (byte) 11, (byte) 11 }),
									1111));
			sel = Selector.open();
			ssc.configureBlocking(false);
			ssc.register(sel, SelectionKey.OP_ACCEPT);
			start = false;
			aid = 0;
			rid = 0;
			wid = 0;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static int rid;
	private static int wid;
	private static int aid;

	//
	private void startServer() throws IOException {
		// TODO Auto-generated method stub
		start = true;
		Iterator<SelectionKey> iKey = null;
		SelectionKey skKey = null;
		System.out.println("Server started.");
		while (start) {
			sel.select();// 不要忘了
			iKey = sel.selectedKeys().iterator();
			if (iKey.hasNext()) {
				// System.out.println("Server=====>>>hasNext");
				skKey = iKey.next();
				iKey.remove();
				if (skKey.isAcceptable()) {
					aid++;
					ServerSocketChannel tSsc = (ServerSocketChannel) skKey
							.channel();
					SocketChannel tSc = tSsc.accept();
					tSc.configureBlocking(false);
					tSc.register(sel, SelectionKey.OP_READ
							| SelectionKey.OP_WRITE);
					System.out.println("The " + aid + "th accept.");
					continue;
				}
				if (skKey.isReadable()) {
					rid++;
					SocketChannel tSc = (SocketChannel) skKey.channel();
					tSc.configureBlocking(false);

					// ByteBuffer的创建方法之一:ByteBuffer.allocate(BUF_SIZE);
					ByteBuffer tBb = ByteBuffer.allocate(BUF_SIZE);

					tSc.read(tBb);
					tBb.flip();
					// 以下做解码用:
					Charset tCs = Charset.forName("gb2312");
					CharBuffer tCb = tCs.newDecoder().decode(tBb);

					System.out.println(tCb);
					System.out.println("The " + rid + "th read.");
					continue;
				}
				if (skKey.isWritable()) {
					wid++;
					SocketChannel tSc = (SocketChannel) skKey.channel();
					tSc.configureBlocking(false);
					// CharBuffer tCb=ByteBuffer.wrap(("The "+wid+"th
					// response.").getBytes()).asCharBuffer();

					// ByteBuffer的创建方法之二:ByteBuffer.wrap(("The "+wid+"th
					// response.").getBytes())
					tSc.write(ByteBuffer.wrap(("The " + wid + "th response.")
							.getBytes()));

					System.out.println("The " + wid + "th write.");
					continue;
				}
			}
		}
	}
}

 

分享到:
评论

相关推荐

    Qt TCPSocket 客户端源码举例

    在IT领域,网络通信是应用程序之间交互的重要方式。Qt库是一个功能强大的跨平台开发框架,...在实践中,还可以考虑添加线程处理以实现非阻塞I/O,或者使用QTcpServer创建服务器端,以实现完整的客户端-服务器通信模型。

    linux 下socket通信中select的用法实例

    可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件...

    Windows Socket 规范及应用

    5. **高性能编程**:引入了异步非阻塞模式,允许在等待数据时执行其他任务,提高了程序效率。 ### 应用举例 在实际应用中,Winsock可用于实现各种网络服务,如聊天软件、文件传输、邮件服务器等。以下是一个简单的...

    JAVA实验典型举例

    这能帮助我们理解数据的输入输出过程以及非阻塞I/O的优势。 Java Swing或JavaFX是构建图形用户界面(GUI)的库,实验可能包含创建窗口、按钮、文本框等组件,以及响应用户事件的处理代码。这对于开发桌面应用至关...

    select的用法举例

    这种机制使得开发者能够实现非阻塞I/O,提高系统的效率。在本篇文章中,我们将深入探讨 `select` 的用法,并通过两个示例——`selectclient` 和 `selectServer` 来展示其在实际应用中的工作原理。 一、`select` ...

    java selector类的用法举例

    为此,Java引入了非阻塞I/O模型(Non-blocking I/O Model),即NIO(New I/O)。在NIO中,最重要的类之一是`Selector`,它提供了高效处理大量连接的能力。本文将详细介绍`Selector`的基本概念及其在Java中的应用实例...

    网络程序设计-第六章.ppt

    在此基础上,开发者需要对两种基本的输入输出模式——阻塞模式和非阻塞模式有深刻的理解。阻塞模式是Winsock接口的默认模式,在这种模式下,当程序执行I/O操作时,会暂停执行直到操作完成。虽然阻塞模式的代码编写...

    Winsock 函数参考

    4. **非阻塞模式**:允许套接字在没有数据可发送或接收时不会阻塞程序执行。 5. **异步操作**:引入了WSAAsyncSelect和WSAEventSelect,支持异步事件通知,增强了网络编程的灵活性。 6. **套接字级广播和多播**:...

    linux programming instances网络编程教程 附源代码

    7.2 非阻塞式i/o 7.2.1 读操作 7.2.2 写操作 7.2.3 建立连接过程 7.2.4 接收连接过程 7.2.5 非阻塞方式的实现 7.3 实例 7.3.1 taik实例 7.3.2 可处理并发服务的echo实例 第8章 套接字属性控制 ...

    shouhu 面试 java 比较全的题目.docx

    - **NIO**:介绍New IO的特性,如非阻塞I/O和选择器(Selector)的使用。 - **文件操作**:File类的功能,以及如何实现文件的复制和删除。 6. **网络编程** - **Socket通信**:讲解TCP和UDP的区别,以及如何在...

    Linux高性能服务器编程

    9.2 poll系统调用 9.3 epoll系列系统调用 9.3.1 内核事件表 9.3.2 epoll_wait函数 9.3.3 LT和ET模式 9.3.4 EPOLLONESHOT事件 9.4 三组IO复用函数的比较 9.5 IO复用的高级应用一:非阻塞connect 9.6 IO复用...

    java面试题.zip

    - **NIO(New IO)**:非阻塞I/O和选择器的使用。 8. **网络编程** - **Socket通信**:客户端与服务器端的建立连接和数据传输。 - **HTTP协议**:了解基本的请求和响应模型。 9. **JVM优化** - **JVM调优工具*...

    11个java面试题及面试技巧

    - 知道NIO(非阻塞I/O)的优势和用法,如Channel、Buffer、Selector。 10. **网络编程**: - 理解TCP和UDP协议,能编写简单的Socket程序。 - 了解HTTP协议,理解客户端和服务器端的交互过程。 11. **框架与库**...

    java面试经验解析.zip

    6. **IO流**:理解字节流和字符流的区别,熟悉FileInputStream、FileOutputStream、BufferedReader、BufferedWriter等常用流类,以及NIO(非阻塞I/O)的基本概念。 7. **反射**:掌握Class类的使用,动态创建对象,...

Global site tag (gtag.js) - Google Analytics