BIO:线程模型
BIO:server demo。缺陷:每一个连接创建一个线程,cpu压力太大。一般不用BIO。
public static void main(String[]args) throws IOException{
ServerSocket serverSocket=new ServerSocket(9000);
while (true){
System.out.println("等待连接");
final Socket socket=serverSocket.accept();
System.out.println("有客户端连接");
//handler(socket);
new Thread(new Runnable() {
public void run() {
try {
handler(socket);
}catch (IOException e){
e.printStackTrace();
}
}
}).start();
}
}
private static void handler(Socket socket) throws IOException {
byte[] bytes=new byte[1024];
System.out.println("准备读取");
int read=socket.getInputStream().read(bytes);
System.out.println("读取完毕");
if(read!=-1){
System.out.println("接收到的数据:"+new String(bytes,0,read));
}
socket.getOutputStream().write("hello client!".getBytes());
socket.getOutputStream().flush();
}
NIO:
NIO:server demo。
public class NioServer {
private static List<SocketChannel> channelList;
public static void main(String[] args) throws IOException {
ServerSocketChannel channel=ServerSocketChannel.open();
channel.socket().bind(new InetSocketAddress(9000));
channel.configureBlocking(false);//非阻塞
System.out.println("server启动成功");
while (true){
SocketChannel socketChannel=channel.accept();
if(socketChannel!=null){
System.out.println("有客户端连接");
socketChannel.configureBlocking(false);//设置读取为非阻塞
channelList.add(socketChannel);
}
Iterator<SocketChannel> i=channelList.iterator();
while (i.hasNext()) {
SocketChannel sc= i.next();
ByteBuffer byteBuffer=ByteBuffer.allocate(128);
int len=sc.read(byteBuffer);
if(len>0){
System.out.println("接收到消息"+new String(byteBuffer.array()));
}else if(len==-1){
i.remove();
System.out.println("客户端断开连接");
}
}
}
}
}
缺陷:当连接很多时,遍历channelList浪费时间,应该遍历有传递消息的连接。
优化:引入多路复用器:
public class NioSelectorServer {
public static void main(String[] args) throws IOException {
ServerSocketChannel channel=ServerSocketChannel.open();
channel.socket().bind(new InetSocketAddress(9000));
channel.configureBlocking(false);//非阻塞
Selector selector=Selector.open();
channel.register(selector, SelectionKey.OP_ACCEPT);//selector注册连接事件
System.out.println("server启动成功");
while (true){
selector.select();//阻塞等待事件发生
Set<SelectionKey> selectionKeys=selector.selectedKeys();//获取全部事件
Iterator<SelectionKey> iterator=selectionKeys.iterator();
while (iterator.hasNext()){//遍历处理所有事件
SelectionKey selectionKey=iterator.next();
if(selectionKey.isAcceptable()){//有客户端连接
SocketChannel socketChannel=((ServerSocketChannel)selectionKey.channel()).accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ);//注册数据读取事件
}else if(selectionKey.isReadable()){//接收到消息
SocketChannel sc= (SocketChannel)selectionKey.channel();
ByteBuffer byteBuffer=ByteBuffer.allocate(128);
int len=sc.read(byteBuffer);
if(len>0){
System.out.println("接收到消息"+new String(byteBuffer.array()));
}else if(len==-1){
sc.close();
System.out.println("客户端断开连接");
}
}
iterator.remove();//去掉处理过的事件
}
}
}
}