网上有比较多的服务端非阻塞的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); // 出错,则打印出错信息
}
}
}
}