Java nio 服务器端读取客户端的输入请求

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

public class ServerChannelTest
{
    public static void main(String[] args)
    {
	new ServerChannelTest().listen();
    }

    public void listen()
    {
	try
	{
	    ByteBuffer bb = ByteBuffer.allocate(1024);
			
	    ServerSocketChannel ssc = ServerSocketChannel.open();
	    ssc.socket().bind(new InetSocketAddress(10011));//绑定端口10011,wildcard ip
	    ssc.configureBlocking(false);// 设置为非阻塞

	    Selector selector = Selector.open();
	    ssc.register(selector, SelectionKey.OP_ACCEPT);// 注册监听
	    debug("注册监听成功!");
			
	    while (true)
	    {
		Thread.sleep(1000);// 为了方便看到输出。
				
		debug("检测是否有SelectionKey,并且select");			
		if (selector.select(1000) <= 0)// 设置timeout为1秒,否则会阻塞在select() 
		{
			continue;
		}// 没有事件被选中
				
		Set<SelectionKey> set = selector.selectedKeys();
		Iterator<SelectionKey> it = set.iterator();
		while (it.hasNext())
		{
		    SelectionKey key = it.next();					
		    debug("取出SelectedKeys");
		    if (key.isAcceptable())
		    {
			debug("ACCEPT key");
			ServerSocketChannel ssChannel = (ServerSocketChannel)key.channel();
			SocketChannel sc = ssChannel.accept();// accept a connection

			// 重要!否则抛出java.nio.channels.IllegalBlockingModeException。
                        // 要与ServerSocketChannel一致。
			sc.configureBlocking(false);
	
			// 注意!不要注册SelectionKey.OP_WRITE.否则每次都能select到它,性能降低。
//			sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
			sc.register(selector, SelectionKey.OP_READ);
		    }
		    else if (key.isReadable())
		    {
			debug("READ key");
			SocketChannel sc = (SocketChannel)key.channel();
			bb.clear();
			if (sc.read(bb) < 0)
			{
			    // read()返回-1表明到达输入流尾。经验证也就是客户端断开了连接。
			    System.out.println("客户端断开了连接");
			    sc.close();
			    break;
			}
			bb.flip();
			System.out.println(bb.get(0));
		    }
//		    else if (key.isWritable())
//		    {
//		        debug("WRITE key");
//		    }// 每次都会取得WRITE key,即使你 不需要。
					
		    it.remove();//删除处理过的key
	        }
	    }
	}
	catch (Exception e)
	{
	     e.printStackTrace();
	}
    }

    public static void debug(String str)
    {
	System.out.println(str);
    }
}

转载于:https://my.oschina.net/u/196340/blog/36684

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值