网上有比较多的服务端非阻塞的nio示例代码。
但客户端基本全是阻塞的。
而我却需要一个非阻塞的客户端(所谓非阻塞关键在于读数据。下面的代码却没有关心读,如果你需要则加上对read感兴趣,之后代码结构还要再修改下)。
下面这个代码主要是看我的电脑最大能打开多少socket客户端(16000多个)。
import java.io.*; import java.net.*; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class TalkClient implements Runnable { // public static List<Socket> socketList=new ArrayList<Socket>(); // public static List<OutputStream> outputList=new ArrayList<OutputStream>(); public static List<SocketChannel> socketList=new ArrayList<SocketChannel>(); public static void main(String[] args) throws InterruptedException, IOException { int clientNum=0; //打开一个选择器 Selector sel = Selector.open(); new Thread(new TalkClient()).start();//写线程 for (int i = 0; i < 100000; i++) { try{ /*//阻塞模式 Socket socket = new Socket("192.168.1.106", 9000); OutputStream out = socket.getOutputStream(); clientNum++; System.out.println("clientNum:"+clientNum); Thread.sleep(80); socketList.add(socket); outputList.add(out); */ //非阻塞模式 //打开套接字通道 SocketChannel socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); SocketAddress socketAddress = new InetSocketAddress("192.168.1.106", 9000); socketChannel.register(sel,SelectionKey.OP_CONNECT);//关心是否可以进行finishConnect操作 //返回false,必须在稍后使用finishConnect()真正建立连接 socketChannel.connect(socketAddress); //选择通道上注册的事件,其相应通道已为I/O操作准备就绪 int num=sel.select(); while(num>=0){ if(num>0){ //返回选择器的已选择键集 Iterator<SelectionKey> it = sel.selectedKeys().iterator(); //获取通道的选择器的键 SelectionKey key = it.next(); it.remove(); //如果该通道已经准备好套接字连接 if(key.isConnectable()){ SocketChannel c=(SocketChannel)key.channel(); //真正建立连接 c.finishConnect(); clientNum++; socketList.add(c); break; } } num=sel.select(); } System.out.println("clientNum:"+clientNum); Thread.sleep(80); } catch (Exception e) { e.printStackTrace(); break; } } } @Override public void run() { while(true){ try { // for (int i = 0;i< outputList.size(); i++) { // OutputStream out=outputList.get(i); // out.write("hello".getBytes()); // Thread.sleep(100); // } for (int i = 0;i< socketList.size(); i++) { SocketChannel socketChannel=socketList.get(i); socketChannel.write(ByteBuffer.wrap("hello".getBytes())); Thread.sleep(100); } Thread.sleep(5000); } catch (Exception e) { System.out.println("Error" + e); // 出错,则打印出错信息 } } } }