> 文章列表 > Java 网络编程 阻塞与非阻塞

Java 网络编程 阻塞与非阻塞

Java 网络编程 阻塞与非阻塞

阻塞模式体会(单线程阻塞只能干一件事)

服务器代码

public class Server {public static void main(String[] args) throws Exception {//创建服务器ServerSocketChannel ssc = ServerSocketChannel.open();//给服务器绑定端口号,以便客户端找到服务器ssc.bind(new InetSocketAddress(8080));//创建List集合来装多个客户端同时发来的消息List<SocketChannel> list = new ArrayList<>();//服务器进行工作while (true){System.out.println("等待连接!");//获取客户段发来的连接SocketChannel sc = ssc.accept();//这是阻塞模式 线程在此处停止System.out.println("连接成功!"+sc.getRemoteAddress());list.add(sc);ByteBuffer byteBuffer = ByteBuffer.allocateDirect(32);//分配缓冲区for (SocketChannel socketChannel : list) {System.out.println("等待客户端的数据输出!");socketChannel.read(byteBuffer);//这是阻塞模式 线程在此处停止byteBuffer.flip();System.out.println(StandardCharsets.UTF_8.decode(byteBuffer).toString());byteBuffer.clear();}}}
}

客户端代码

public class Client {public static void main(String[] args) throws Exception {SocketChannel sc = SocketChannel.open();sc.connect(new InetSocketAddress("localhost",8080));System.out.println("我开始发送数据");}
}

体会结果

客户端程序没有启动 accept()方法被阻塞,线程停止

 客户端程序debug启动 没有数据输出!此时read()方法被阻塞,线程停止

 客户端程序写入数据!服务器继续往下执行等待下一次的链接

 但是这时客户端再次写数据,服务器没有响应。

 若在这时再开启一个客户端线程连接服务器(之前的操作的有点失误,重新来了一遍端口号变了)

但是结果还是一样的,在list集合中我们保存了第一个客户端的连接,所以上此图的第二次写的内容在第二个客户端连接的时候,就会被执行。

 非阻塞模式(单线程做牛做马)

服务器代码(socketChannel.configureBlocking(false))

public class Server {public static void main(String[] args) throws Exception {//创建服务器ServerSocketChannel ssc = ServerSocketChannel.open();ssc.configureBlocking(false);//设置非阻塞//给服务器绑定端口号,以便客户端找到服务器ssc.bind(new InetSocketAddress(8080));//创建List集合来装多个客户端同时发来的消息List<SocketChannel> list = new ArrayList<>();//服务器进行工作while (true){Thread.sleep(1000);System.out.println("等待连接!");//获取客户段发来的连接SocketChannel sc = ssc.accept();//这是非阻塞模式 返回值null;继续往下执行if (sc != null){sc.configureBlocking(false);System.out.println("连接成功!"+sc.getRemoteAddress());list.add(sc);Thread.sleep(1000);}ByteBuffer byteBuffer = ByteBuffer.allocateDirect(32);//分配缓冲区for (SocketChannel socketChannel : list) {System.out.println("等待客户端的数据输出!");socketChannel.read(byteBuffer);//这是非阻塞模式 返回值0byteBuffer.flip();System.out.println(StandardCharsets.UTF_8.decode(byteBuffer).toString());byteBuffer.clear();}}}
}