【问题标题】:UDP datagram is sent but never receivedUDP 数据报已发送但从未收到
【发布时间】:2021-09-24 21:46:23
【问题描述】:

我为客户端和服务器创建了两个不同的 java 类,每个类都有发送和接收方法。根据任务,我必须通过DatagramPacket 建立服务器到客户端的连接,并通过DatagramChannel 建立客户端到服务器的连接。最后一个效果很好,但是我在处理数据报时遇到了麻烦——它们是从服务器发送的,而客户端从来没有收到过。怎么了?

public class TransferClient implements Serializable{
    private static final long serialVersionUID = 26L;
    public TransferClient() {

    }

    public void send(Command com) throws IOException {
        SocketAddress socketAddressChannel = new InetSocketAddress("localhost", 1);
        DatagramChannel datagramChannel=DatagramChannel.open();
        ByteBuffer bb;
        datagramChannel.connect(socketAddressChannel);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(com);
        oos.flush();
        bb=ByteBuffer.wrap(baos.toByteArray(),0, baos.size());
        datagramChannel.send(bb,socketAddressChannel);
        baos.close();
        oos.close();
    }

    public Command receive() throws IOException, ClassNotFoundException {
        SocketAddress address = new InetSocketAddress(2029);
        DatagramSocket s = new DatagramSocket();
        DatagramPacket inputPacket = new DatagramPacket(new byte[1024],1024, address);
        s.receive(inputPacket);
        ByteArrayInputStream bais = new ByteArrayInputStream(inputPacket.getData());
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (Command) ois.readObject();
    }
}

public class TransferServer {
    public TransferServer(){

    }

    public void send(Command com) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        byte[] buffer;
        oos.writeObject(com);
        oos.flush();
        buffer=baos.toByteArray();
        SocketAddress address = new InetSocketAddress("localhost",2029);
        DatagramSocket s = new DatagramSocket();
        DatagramPacket outputPacket = new DatagramPacket(buffer,buffer.length,address);
        s.send(outputPacket);
    }


    public Command receive() throws IOException, ClassNotFoundException {
            SocketAddress socketAddressChannel = new InetSocketAddress("localhost", 1);
            DatagramChannel datagramChannel = DatagramChannel.open();
            datagramChannel.bind(socketAddressChannel);
            ByteBuffer bb = ByteBuffer.allocate(1024);
            datagramChannel.receive(bb);
            ByteArrayInputStream bais = new ByteArrayInputStream(bb.array());
            ObjectInputStream ois = new ObjectInputStream(bais);
            Command command;
            System.out.println(ois.available());
            command =(Command) ois.readObject();
            datagramChannel.close();
            ois.close();
            bais.close();
            return command;
    }
}

【问题讨论】:

  • 1024 以下的端口受到保护。看起来您使用的数字非常少。
  • 哦,天哪,我更改了端口,但没有帮助。不过,谢谢!

标签: java udp datagram


【解决方案1】:

您必须指定绑定DatagramSocket 的端口才能接收您的数据。否则它将绑定到您机器上找到的第一个可用端口。

这里你不需要SocketAddress,但你需要考虑实际接收到的数据包长度。

java.net.DatagramSocket Documentation

TransferClient 类的receive() 方法中:

public Command receive() throws IOException, ClassNotFoundException {

    DatagramSocket s = new DatagramSocket(2029); //Add your port Here

    DatagramPacket inputPacket = new DatagramPacket(new byte[1024],1024);
    s.receive(inputPacket);
    ByteArrayInputStream bais = new ByteArrayInputStream(inputPacket.getData(), 0, packet.getLength());
    ObjectInputStream ois = new ObjectInputStream(bais);
    return (Command) ois.readObject();
}

【讨论】:

  • 但随后会抛出 BindException: Address already in use: bind.为了澄清这种情况:首先我将数据从客户端发送到服务器,然后从服务器发送到客户端。
  • 请务必不要在服务器的send()方法中设置DatagramSocket的端口,这可能是导致异常的原因。
  • 我没有在服务器的send()方法中设置。
  • 其实我是在发送包里面设置的。会不会导致这个异常?
  • 这是因为你每次进入这个方法都是在打开一个socket,而从来没有关闭它。您应该进入方法之前创建套接字,一次,并在完全完成后关闭它。
猜你喜欢
  • 2018-09-30
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
相关资源
最近更新 更多