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日
    浏览(63)
  • 计算机网络技术与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日
    浏览(53)
  • Java网络编程(一)基本网络概念

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

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

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

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

    两台设备之间通过网络实现数据传输,将数据通过网络从一台设备传输到另一台设备 网络 两台或多台设备通过一定物理设备连接起来构成了网络 网络又分为: 局域网:覆盖范围最小,仅仅覆盖一个教室或一个机房 城域网:覆盖范围较大,可以覆盖一个城市 广域网:覆盖范围最大

    2024年02月12日
    浏览(38)
  • JAVA网络编程(一)

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

    2024年02月07日
    浏览(36)
  • java22-网络编程

    java是internet上的语言,它从语言级上提供了对网络应用程序的支持 java提供网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在Java本机安装系统里,由JVM控制 直接或者间接的通过网络协议与其它计算机实现数据交换,进行通讯 IP IntAddress类 端口号 端口号加IP地址组

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

    Java网络编程基于TCP/UDP协议的基础之上,TCP/IP协议是一个协议簇。里面包括很多协议的,UDP只是其中的一个, 之所以命名为TCP/IP协议,因为TCP、IP协议是两个很重要的协议,就用他两命名了。那么首先我们先介绍一下TCP和UDP的特点: 1.TCP(Transmission Control Protocol,传输控制协议

    2024年02月08日
    浏览(43)
  • Java 网络编程(大全)

    读者手册(必读)_云边的快乐猫的博客-CSDN博客 一、1网络通信的基本模式分为两种 1.CS模式 (Client---客户端,Server---服务端)  客户端是需要程序员去开发的,例如日常使用的各种的APP,服务端就是服务器。 例子:端游,依赖特定的PC端才能玩。 2.BS模式 (Browser---浏览器,

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

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

    2024年02月08日
    浏览(43)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包