java-套接字在尝试读取/发送时关闭

epfja78i  于 2021-07-08  发布在  Java
关注(0)|答案(0)|浏览(204)

我试图用java实现一个套接字的侦听器 DataSocket ,所以我创建了一个新的listener类 ExecutorService 在自己的线索上运行。在同一个类中,我想创建另一个方法,该方法也将通过同一个套接字将消息发送到同一个地址(因为该服务器也在等待我的答案)。
由于某种原因,套接字一直处于关闭状态,我得到了一个异常。
我用w while 循环等待消息,当我得到响应时,我使用回调发送一个答案。
这是实现:这是侦听器类:

public class MessageListener implements IMessageTransport {

    private final static int TIMEOUT_MILLIS = 300;
    private final int port = 12000;
    private InetAddress address;

    private DatagramSocket socket;

    private Executor executor;

    public MessageListener(String address, Executor executor) {
        this.executor = executor;

        try {
            this.address = InetAddress.getByName(address);
            socket = new DatagramSocket(null);
            SocketAddress sockaddr = new InetSocketAddress(this.address, port);
            socket.bind(sockaddr);
            socket.setSoTimeout(TIMEOUT_MILLIS);
        } catch (SocketException | UnknownHostException e) {
            e.printStackTrace(); // todo - handle exception
        }
    }

    public void start(final MessageTransportCallback callback) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("heresa");
                listen(callback);
            }
        });
    }

    public void send(byte[] message) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("heresa");
                sendMessage(message);
            }
        });
    }

    private void sendMessage(byte[] message) {
        System.out.println("Sending message: " + bytesToHex(message));
        try {
            DatagramPacket request = new DatagramPacket(message, message.length, this.address, this.port);
            socket.send(request);
        } catch (SocketTimeoutException e1) {
            System.out.println("timeout");
        } catch (IOException e) {
            e.printStackTrace(); // todo - handle exception
        }
    }

    private void listen(final MessageTransportCallback callback) {
        DatagramPacket reply;
        System.out.println("here");

        while (true) {
            try {
                byte[] data = new byte[2048];
                reply = new DatagramPacket(data, data.length);
                socket.receive(reply);
                if (reply.getLength() != 0) {
                    System.out.println("Read bytes: " + bytesToHex(reply.getData()));
                    callback.onComplete(Arrays.copyOfRange(reply.getData(), 0, reply.getLength()));
                }
            } catch (SocketTimeoutException e1) {
//                System.out.println("timeout?");
            } catch (IOException e) {
                e.printStackTrace(); // todo - handle exception
            }
        }
    }
}

这就是我发送信息和启动侦听器的方式:

final ExecutorService executorService = Executors.newFixedThreadPool(5);
MessageListener messageListener = new MessageListener(address, executorService);
messageListener.start(new MessageTransportCallback() {
    @Override
    public void onComplete(byte[] response) {
        System.out.println(response);
    }
});
messageListener.send(bytemessage);

虽然我得到一个绑定套接字错误:

java.net.BindException: Cannot assign requested address: Cannot bind
    at java.base/java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
    at java.base/java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:84)
    at java.base/java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:117)
    at java.base/java.net.DatagramSocket.bind(DatagramSocket.java:395)
    at main.MessageListener.<init>(MessageListener.java:33)
    at main.Main.main(Main.java:194)

但奇怪的是,如果我像这样向套接字发送消息,它就会工作:

DatagramPacket request = new DatagramPacket(message, message.length, this.address, this.port);
socket.send(request);

这意味着套接字不会以这种方式返回绑定错误,但是,我不能像这样侦听套接字,我只能在发送消息之后才收到消息。。。
以及我为什么得到 bind 错误?如何创建一个具有侦听新消息的线程和发送消息的线程的套接字?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题