有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java:使用两个不同的输入源和

关于StackOverflow的第一个问题,如果我问错了,请原谅

基本上,我正在编写一个多播客户端,它无限期地侦听多播地址,直到用户在控制台中键入“退出”。我发现为MulticastSocket设置SO_超时、检查是否键入了“quit”,然后返回到receive方法调用实际上不起作用,因为在超时和检查控制台块之后可以立即发送数据包。因此,我认为最好的选择是简单地让两个线程运行,其中一个线程侦听socket并阻塞,直到它接收到某些内容,另一个线程侦听控制台,直到被告知退出。我唯一的问题是,我不确定如何让控制台侦听线程告诉socket线程关闭socket并终止。系统end()可以工作,但我担心我会留下一个插座打开,等等

TLDR;类的主方法是否可以启动线程,然后在线程结束后以特定方式响应?我需要在一个线程上侦听控制台,在另一个线程上侦听多播socket,或者只在客户端类的main中侦听

谢谢大家


共 (1) 个答案

  1. # 1 楼答案

    我会调用Socket.close()来关闭套接字。这将在该线程中生成IOException。因此,在执行此操作之前,我将设置一个类似closed = true;的标志,并让另一个线程在打印错误之前对此进行检查,即,如果已关闭,则不打印IOException。像这样的

    public class SocketListener implements Runnable, Closeable {
        final MulticastSocket socket;
        final Consumer<DatagramPacket> packetConsumer;
        volatile boolean closed;
    
        public SocketListener(MulticastSocket socket, Consumer<DatagramPacket> packetConsumer) {
            this.socket = socket;
            this.packetConsumer = packetConsumer;
        }
    
        @Override
        public void run() {
            DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
            try {
                while(!closed) {
                    socket.receive(packet);
                    packetConsumer.accept(packet);
                }
            } catch (IOException e) {
                if (!closed)
                    e.printStackTrace();
            }
        }
    
        @Override
        public void close() throws IOException {
            closed = true;
            socket.close();
        }
    }
    

    例如,在主线程中,您可以

    MulticastSocket socket = ...
    Consumer<DatagramPacket> packetConsumer = ...
    try (SocketListener listener = new SocketListener(socket, packetConsumer)) {
        boolean finished = false;
        do {
            // read from the console
            if (some condition)
                finished = true;
        } while(!finished);
    } // calls close() for you.