SocketChannel

服务端代码:

public static void main(String[] args) throws Exception 
	{
		// 创建选择器  
		Selector selector = Selector.open();
		// 打开监听信道  
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		// 与本地端口绑定  
		serverSocketChannel.socket().bind(new InetSocketAddress(9999));
		// 设置为非阻塞模式 
		serverSocketChannel.configureBlocking(false); 
		// 将选择器绑定到监听信道,只有非阻塞信道才可以注册选择器.并在注册过程中指出该信道可以进行Accept操作  
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

		while (true) 
		{
			// 等待某信道就绪
			int selectInt = selector.select();
			if (selectInt == 0)
				continue;
			// 取得迭代器.selectedKeys()中包含了每个准备好某一I/O操作的信道的SelectionKey
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			while (iterator.hasNext())
			{
				SelectionKey selectionKey = iterator.next();
				// 有客户端连接请求时 
				if (selectionKey.isAcceptable())
					handleAccept(selectionKey);
				// 从客户端读取数据  
				if (selectionKey.isReadable())
					handleRead(selectionKey);
				// 向客户端发送数据
			    if (selectionKey.isWritable())
					handleWrite(selectionKey);
				iterator.remove();
			}
		}
	}

	public static void handleAccept(SelectionKey selectionKey) throws Exception
	{
		// 返回创建此键的通道,接受客户端建立连接的请求,并返回 SocketChannel 对象
		ServerSocketChannel ServerSocketChannel = (ServerSocketChannel)selectionKey.channel();
		SocketChannel clientChannel = ServerSocketChannel.accept();
		// 非阻塞式 
		clientChannel.configureBlocking(false);
		// 注册到selector
		clientChannel.register(selectionKey.selector(), SelectionKey.OP_READ);

		sendInfo(clientChannel, "连接服务器成功!");
		System.err.println("client IP :" + clientChannel.socket().getRemoteSocketAddress());
	}

	public static void handleRead(SelectionKey key) throws Exception
	{
		SocketChannel channel = (SocketChannel) key.channel();
		String msg = "";
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		while(channel.read(buffer) > 0)
		{
			buffer.flip();
			while(buffer.hasRemaining())
				msg += new String(buffer.get(new byte[buffer.limit()]).array());
			buffer.clear();
		}  

        System.err.println("收到客户端消息:"+msg);
        
        sendInfo(channel, "服务端消息test!");
	}

	public static void handleWrite(SelectionKey key)
	{
		System.out.println("服务端发送信息!");
	}

	public static void sendInfo(SocketChannel clientChannel, String msg) throws Exception
	{
		// 向客户端发送连接成功信息
		clientChannel.write(ByteBuffer.wrap(msg.getBytes()));
	}

客户端代码:

	public static void main(String[] args) throws Exception 
	{
		// 创建选择器  
		Selector selector = Selector.open();
		SocketChannel socketChannel = SocketChannel.open();
		socketChannel.configureBlocking(false);
		socketChannel.connect(new InetSocketAddress("localhost", 9999));
		socketChannel.register(selector, SelectionKey.OP_CONNECT); 

		while (true) 
		{
			int selectInt = selector.select();
			if (selectInt == 0)
				continue;
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			while(iterator.hasNext())
			{
				SelectionKey key = iterator.next();
				if (key.isConnectable())
					handleConnect(key);
				if (key.isReadable())
					handleRead(key);
				if (key.isWritable())
					handleWrite(key);
				iterator.remove();
			}
		}

	}

	public static void handleConnect(SelectionKey key) throws Exception
	{
		SocketChannel channel = (SocketChannel) key.channel();
		if (channel.isConnectionPending())
			channel.finishConnect();
		channel.configureBlocking(false);
		channel.register(key.selector(), SelectionKey.OP_READ);

		sendInfo(channel, "客户端测试!");
	}

	public static void handleRead(SelectionKey key) throws Exception
	{
		SocketChannel channel = (SocketChannel) key.channel();
		String msg = "";
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		while(channel.read(buffer) > 0)
		{
			buffer.flip();
			while(buffer.hasRemaining())
				msg += new String(buffer.get(new byte[buffer.limit()]).array());
			buffer.clear();
		}   

        System.err.println("收到服务端消息:"+msg);
	}

	public static void handleWrite(SelectionKey key) throws Exception
	{
		System.err.println("客户端写数据!");
	}

	public static void sendInfo(SocketChannel clientChannel, String msg) throws Exception
	{
		// 向客户端发送连接成功信息
		clientChannel.write(ByteBuffer.wrap(msg.getBytes()));
	}

参考地址:http://www.iteye.com/magazines/132-Java-NIO

时间: 2024-10-27 07:48:54

SocketChannel的相关文章

Java NIO系列教程(八) SocketChannel

Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道.可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的某台服务器. 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel. 打开 SocketChannel 下面是SocketChannel的打开方式: 1 SocketChannel socketChannel = SocketChannel.open(); 2 socke

Java之NIO(二)selector socketChannel

上篇文章对NIO进行了简介,对Channel和Buffer接口的使用进行了说明,并举了一个简单的例子来说明其使用方法. 本篇则重点说明selector,Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 与selector联系紧密的是ServerSocketChannel和SocketChannel,他们的使用与上篇文章描述的FileChannel的使用方

Java千百问_02基本使用(012)_如何编写非阻塞SocketChannel程序

点击进入_更多_Java千百问 1.如何编写非阻塞SocketChannel程序 了解Socket看这里:Socket是什么 了解 SocketChannel看这里:Socket.SocketChannel有什么区别 使用SocketChannel的最大好处就是可以进行非阻塞IO,每次链接后都会直接返回,不会阻塞线程.将需要多个线程的任务通过几个线程就能完成,降低了了性能消耗. 了解阻塞.非阻塞看这里:阻塞.非阻塞有什么区别 要编写SocketChannel,需要了解java.nio包中如下几个

健壮的、便捷的、异步的SocketChannel实现(转)

Socket通信比较常见的问题有如下几种: 1.设置收发超时: 2.正确的每一个bit的收发: 3.物理线路故障的保护: 4.始终能正常工作: 5.尽量少占系统资源: n.…… 而Socket编程有一个共性,尽管100个人可能会写出1000种实现,但做的事情却只有一种,就是: 通信. 为此,通过学习dnsjava的通信代码,加上自己在一些项目中的实践,现在给出TCP通信的例子实现如下,希望能够给想偷懒的人一个简单的解决方案. 本方案在正常的局域网连接中测试过几百万次没什么问题.缺乏更艰苦的环境,

Java NIO SocketChannel

Java Nio 1 Java NIO Tutorial 2 Java NIO Overview 3 Java NIO Channel 4 Java NIO Buffer 5 Java NIO Scatter / Gather 6 Java NIO Channel to Channel Transfers 7 Java NIO Selector 8 Java NIO FileChannel 9 Java NIO SocketChannel 10 Java NIO ServerSocketChan

SocketChannel API用法

java.nio.channels 类 SocketChannel java.lang.Object java.nio.channels.spi.AbstractInterruptibleChannel java.nio.channels.SelectableChannel java.nio.channels.spi.AbstractSelectableChannel java.nio.channels.SocketChannel 所有已实现的接口: Closeable, ByteChannel

Java千百问_01基本概念(013)_Socket、SocketChannel有什么区别

点击进入_更多_Java千百问 1.Socket.SocketChannel有什么区别 了解Socket看这里:Socket是什么 Socket.SocketChannel二者的实质都是一样的,都是为了实现客户端与服务器端的连接而存在的,但是在使用上,却有很大的区别.具体如下: 所属包不同 Socket在java.net包中,而SocketChannel在java.nio包中. 异步方式不同 从包的不同,我们大体可以推断出他们主要的区别:Socket是阻塞连接(当然我们可以自己实现非阻塞),So

Java基础知识强化之IO流笔记79:NIO之 SocketChannel

1. Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道.可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的某台服务器. 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel. 2.   (1)打开 SocketChannel 下面是SocketChannel的打开方式: 1 SocketChannel socketChannel = SocketChannel.open

SocketChannel 例子(转)

Socket通信比较常见的问题有如下几种: 1.设置收发超时: 2.正确的每一个bit的收发: 3.物理线路故障的保护: 4.始终能正常工作: 5.尽量少占系统资源: n.…… 而Socket编程有一个共性,尽管100个人可能会写出1000种实现,但做的事情却只有一种,就是:通信. 为此,通过学习dnsjava的通信代码,加上自己在一些项目中的实践,现在给出TCP通信的例子实现如下,希望能够给想偷懒的人一个简单的解决方案. 本方案在正常的局域网连接中测试过几百万次没什么问题.缺乏更艰苦的环境,所