Java 网络编程 —— 异步通道和异步运算结果

这篇具有很好参考价值的文章主要介绍了Java 网络编程 —— 异步通道和异步运算结果。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

从 JDK7 开始,引入了表示异步通道的 AsynchronousSockerChannel 类和 AsynchronousServerSocketChannel 类,这两个类的作用与 SocketChannel 类和 ServerSockelChannel 相似,区别在于异步通道的一些方法总是采用非阻塞模式,并且它们的非阻塞方法会立即返回一个 Future 对象,用来存放方法的异步运算结果

AsynchronousSocketChannel 类有以下非阻塞方法:

// 连接远程主机
Future<Void> connect(SocketAddress remote);
// 从通道中读入数据,存放到ByteBuffer中
// Future对象包含了实际从通道中读到的字节数
Future<Inleger> read(ByteBuffer dst);
// 把ByteBuffer的数据写入通道
// Future对象包含了实际写入通道的字节数
Future<Integer> write(ByteBuffer src);

AsynchronousServerSocketChannel 类有以下非阻塞方法:

// 接受客户连接请求
// Future对象包含连接建立成功后创建的AsynchronousSockelChannel对象
Future<AsynchronousSocketChannel> accept();

使用异步通道,可以使程序并行执行多个异步操作,例如:

SocketAddress socketAddress = ...;
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();

//请求建立连接
Future<Void> connected = client.connect(socketAddress);
ByteBuffer byteBuffer = ByteBuffer.allocate(128);

//执行其他操作
//...

//等待连接完成
connected.get();

//读取数据
Future<Integer> future = client.read(byteBuffer);

//执行其他操作
//...

//等待从通道读取数据完成
future.get();

byteBuffer.flip();
WritableByteChannel out = Channels.newChannel(System.out);
out.write(byteBuffer);

下例的代码演示了异步通道的用法,它不断接收用户输入的域名并尝试建立连接,最后打印建立连接所花费的时间。如果程序无法连接到指定的主机,就打印相关错误信息。如果用户输入 bye,就结束程序

//表示连接一个主机的结果
class PingResult {
    
    InetSocketAddress address;
    long connectStart; //开始连接时的时间
    long connectFinish = 0; //连接成功时的时间
    String failure;
    Future<Void> connectResult; //连接操作的异步运算结果
    AsynchronousSocketChannel socketChannel;
    String host;
    final String ERROR = "连接失败";
        
    PingResult(String host) {
        try {
            this.host = host;
            address = new InetSocketAddress(InetAddress.getByName(host), 80);
        } catch (IOException x) {
            failure = ERROR;
        }
    }
    
    //打印连接一个主机的执行结果
    public void print() {
        String result;
        if (connectFinish != 0) {
            result = Long.toString(connectFinish - connectStart) + "ms";
        } else if (failure != null) {
			result = failure;
        } else {
            result = "Timed out";
        }
        System,out,println("ping "+ host + "的结果" + ":" + result);
    }
    
    public class PingClient {
        //存放所有PingResult结果的队列
        private LinkedList<PingResult> pingResults = new Linkedlist<PingResult>();
        boolean shutdown = false;
        ExecutorService executorService;
        
        public PingClient() throws IOException {
            executorService = Executors.newFixedThreadPool(4);
            executorService.execute(new Printer());
            receivePingAddress();
        }
    }
    
    public static void main(String args[]) throws IOException {
        new PingClient();
    }
    
    /*接收用户输入的主机地址,由线程池执行PingHandler任务 */
    public void receivePingAddress() {
        try {
            BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
            String msg = null;
            //接收用户输入的主机地址
            while((msg = localReader.readLine()) != null) {
                if(msg.equals("bye")) {
                    shutdown = true;
                    executorService.shutdown();
                    break;
                }
                executorService.execute(new PingHandler(msg));
            }
        } catch(IOException e) {}
    }
    
    /* 尝试连接特定主机,生成一个PingResult对象,把它加入PingResults结果队列中 */
    public class PingHandler implements Runnable {
        String msg;
        public PingHandler(String msg) {
            this.msg = msg;
        }
        public void run() {
            if(!msg.equals("bye")) {
                PingResult pingResult = new PingResult(msg);
                AsynchronousSocketChannel socketChannel = null;
                try {
                    socketChannel = AsynchronousSocketChannel.open();
                    pingResult.connectStart = System.currentTimeMillis();
                    synchronized (pingResults) {
                        //向pingResults队列加入一个PingResult对象
                        pingResults.add(pingResult);
                        pingResults,notify();
                    }
                    Future<Void> connectResult = socketChannel.connect(pingResult.address);
                    pingResult.connectResult = connectResult;
                } catch (Exception x) {
                    if (socketChannel != null) {
                        try { socketChannel.close();} catch (IOException e) {)
                    }
                    pingResult.failure = pingResult.ERROR;
                }
            }
        }
    }
    
    /* 打印PingResults结果队列中已经执行完毕的任务的结果 */
    public class Printer implements Runnable {
        public void run() {
            PingResult pingResult = null;
            while(!shutdown) {
                synchronized (pingResults) {
                    while (!shutdown && pingResults.size() == 0 ) {
                        try {
                            pingResults.wait(100);
                        } catch(InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    if(shutdown && pingResults.size() == 0 ) break;
                    pingResult = pingResults.getFirst();
                    
                    try {
                        if(pingResult.connectResult != null) {
                            pingResult.connectResult.get(500, TimeUnit,MILLISECONDS);
                        } catch(Exception e) {
                            pingResult.failure = pingResult.ERROR;
                        }
                    }
                    
                    if(pingResult.connectResult != null && pingResult.connectResult.isDone()) {
                        pingResult.connectFinish = System.currentTimeMillis();
                    }
                    
                    if(pingResult,connectResult != null && pingResult.connectResult.isDone() || || pingResult,failure != null) {
                        pingResult.print();
                        pingResults.removeFirst();
                        try {
                            pingResult.socketChannel.close();
                        } catch (IOException e) {}
                    }
                }
            }
        }
    }
}

PingClient 类定义了两个表示特定任务的内部类:文章来源地址https://www.toymoban.com/news/detail-453064.html

  • PingHandler:负责通过异步通道去尝试连接客户端输入的主机地址,并且创建一个 PingResult 对象,它包含了连接操作的异步运算结果,再将其加入 PingResults 结果队列
  • Printer:负责打印 PingResults 结果队列已经执行完毕的任务结果,打印完毕的 PingResult 对象会从队列中删除

到了这里,关于Java 网络编程 —— 异步通道和异步运算结果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机网络技术与JAVA网络编程URL编程-----JAVA入门基础教程-----计算机网络经典

    import org.junit.jupiter.api.Test; import java.io.*; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class URLTest { public static void main(String[] args) { //URL:统一资源定位符(种子),一个URL就定位着互联网上某个资源的地址 //http:应用层协议,IP地址,端口号,资源地址,参数

    2024年02月15日
    浏览(57)
  • 计算机网络技术与JAVA网络编程UDP编程-----JAVA入门基础教程-----计算机网络经典

    import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.*; public class UDP { public static void main(String[] args) { DatagramSocket datagramSocket = null; try { datagramSocket = new DatagramSocket(); InetAddress inetAddress = InetAddress.getByName(\\\"127.0.0.1\\\"); int port = 9090; byte[] byte

    2024年02月15日
    浏览(49)
  • Java网络编程(一)基本网络概念

            网络(network) 是几乎可以实时相互发送和接收数据的计算机和其他设备的集合。网络通常用线缆连接,数据位转换为电磁波,通过线缆移动。不过,无线网络会通过无线电波传输数据,许多长距离的传输现在会用通过玻璃纤维发送可见光的光纤电缆来完成。传输数

    2024年02月16日
    浏览(42)
  • Java 网络编程 —— 安全网络通信

    SSL(Secure Socket Layer,安全套接字层)是一种保证网络上的两个节点进行安全通信的协议。IETF(Interet Engineering Task Force)国际组织对 SSL 作了标准化,制定了 RFC2246 规范,并将其称为传输层安全(Transport Layer Security,TLS) SSL 和 TLS 都建立在 TCP/IP 的基础上,一些应用层协议,如

    2024年02月11日
    浏览(38)
  • Java——网络编程

    InetAddress类 java.net.InetAddress类用来封装计算机的IP地址和DNS(没有端口信息),它包括一个主机名和一个ip地址,是java对IP地址的高层表示。大多数其他网络类都要用到这个类,包括Sorket、ServerSocker、URL、DatagramSorket、DatagramPacket等 常用静态方法 getLocalHost()得到本机的InetAddress对象,其

    2024年03月16日
    浏览(37)
  • JAVA网络编程(一)

    定义 :在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 应用场景 :即时通信,网游,邮件等 不管什么场景,都是计算机与计算机之间通过网络在进行数据传输 java提供一个java.net包,可以帮助我们开发网络应用程序。 CS架构是指在远端有一个服务器Server,

    2024年02月07日
    浏览(33)
  • Java网络编程知识

    目录 1.网络编程概述 1.网络编程的目的 2.网络编程的三个问题 1.如何准确定位网络上的主机? 2.如何定位主机上的特定应用? 3.找到主机后如何可靠高效的进行数据传输? 2.通信要素一:IP和端口号 1.IP地址 2.端口号 3.套接字 3.通信要素二:网络协议 1.使用TCP协议通信 1.客户端

    2024年02月08日
    浏览(41)
  • Java 网络编程基础

    一个网络请求、服务之间的调用都需要进行网络通讯,在日常开发时我们可能并不会关心我们的服务端是怎么接收到请求的、调用别的服务是怎么调用的,都是直接使用现成的框架或工具,比如,Tomcat、Dubbo、OkHttp等提供网络服务的框架。作为程序员,我们还是要知其然知其

    2024年02月15日
    浏览(35)
  • Java-网络编程

    网络是指通过电缆、无线电波或者其他方法连接在一起的一系列节点的集合。在计算机科学和信息技术领域,网络特指计算机网络,它是一组相互连接的、自治的计算机系统。 🏢 边缘部分 连接网络的计算机、手机、服务器等 🔗 核心部分 路由器、交换机等设备 负责数据传

    2024年02月13日
    浏览(36)
  • 【Java】网络编程

    Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基 于Socket套接字的网络程序开发就是网络编程 流套接字 : 使用传输层TCP协议 特点 有连接,可靠传输,面向字节流,有接收缓冲区也有发送缓冲区,大小不限 对于字节流来说,可以简单

    2024年02月10日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包