在java的套接字编程中,大部分一般使用阻塞IO套接字编程。套接字的读取和写入会阻塞(也就是说不管现在有没有写入/读出数据 调用read和write方法将会阻塞)。而NIO将I/O事件注册,当特定的注册I/O事件到达时会通知您。不需要轮询,也不需要创建大量的线程下面一个例子:下载
Server代码
package simple.socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
/**
* Created by banxia on 16/10/12.
*/
public class UseNioSocket {
public static void main(String[] args) throws IOException {
// 创建一个selector 对象
Selector selector = Selector.open();
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ssc.socket().bind(new InetSocketAddress(8888));
ssc.register(selector, SelectionKey.OP_ACCEPT);
ByteBuffer buffer = ByteBuffer.allocate(1024);
System.out.println("服务已经启动端口:" + 8888);
while (true) {
int selectNum = selector.select();
System.out.println("selectNum=" + selectNum);
if (selectNum <= 0) {
continue;
}
// 获取
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
if (key.readyOps() == SelectionKey.OP_ACCEPT) {
// 接收 accept
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
SocketChannel accept = channel.accept();
accept.configureBlocking(false);
System.out.println("接收客户端:" + accept.socket().getInetAddress().getHostAddress() + ":" + accept.socket().getPort());
accept.register(selector, SelectionKey.OP_READ);
it.remove();
} else {
SocketChannel sc = (SocketChannel) key.channel();
System.out.println("接收客户端:" + sc.socket().getInetAddress().getHostAddress() + ":" + sc.socket().getPort() +"开始处理...");
while (true) {
buffer.clear();
long l = sc.read(buffer);
if (l <= 0) {
break;
}
System.out.print(".");
buffer.flip();
sc.write(buffer);
}
System.out.print("\n");
it.remove();
System.out.println("接收客户端:" + sc.socket().getInetAddress().getHostAddress() + ":" + sc.socket().getPort() +"处理完成处理...");
}
}
}
}
}