Java UDP数据包仅容纳5位

标签 java sockets udp

以下代码用于发送格式为“address,porttNum”的简单字符串。

这是客户端:

ByteArrayInputStream bin = new ByteArrayInputStream(packet.getData());
DataInputStream dis = new DataInputStream(bin);

try {
            System.out.println("Data in packet: " + dis.readLine());
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

这是服务器端:

byte[] sbuf = data.getBytes();
        // sbuf = output.getBytes();
        packet = new DatagramPacket(sbuf,
                sbuf.length, packet.getAddress(), packet.getPort());
try { 
            socket = new DatagramSocket();
            socket.send(packet);
        } catch (Exception e) {
            e.printStackTrace();
        }

假设服务器发送“abcdefghi”,客户端只收到“abcde”。我已经尝试过多个测试用例,客户端总是收到 5 个字节。谁能指出我哪里搞砸了?

编辑: 为了调试目的,我什至添加了以下内容:

try {
            System.out.println("Data in packet: " + dis.readLine());
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

它输出了正确的数据,但客户端仍然无法获取它。

编辑2: 我将客户端更改为以下内容:

String data = new String(packet.getData(), StandardCharsets.UTF_8);
        System.out.println("Data in packet: " + data);

没有什么区别。

最佳答案

下面是一些示例代码,展示了从字符串字节构造数据报包、发送数据包以及重建字符串。

请注意,创建的用于接收数据包的缓冲区比最终接收到的消息大得多。这是必要的,因为如果 UDP 套接字接收到大于缓冲区的消息,则会将消息截断为缓冲区的大小。例如,如果客户端向服务器发送消息“ZYXWV”,并且只为该消息创建了足够大的缓冲区,然后为传入消息重用该缓冲区,则仅使用该消息的前 5 个字符将收到传入消息。

public class DataGram {

    public static void main(String[] args) throws SocketException {
        new Thread(new Client()).start();
        new Thread(new Server()).start();
    }

    static class Client implements Runnable {
        DatagramSocket socket;

        Client() throws SocketException {
            socket = new DatagramSocket(1234);
        }

        @Override
        public void run() {
            byte[] buf = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            try {
                try {
                    socket.receive(packet);
                    String msg = new String(packet.getData());
                    System.out.println(msg);
                } finally {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static class Server implements Runnable {

        @Override
        public void run() {
            SocketAddress address = new InetSocketAddress("localhost", 1234);
            try (DatagramSocket socket = new DatagramSocket()) {
                String msg = "abcdefghi";
                byte[] buf = msg.getBytes();
                DatagramPacket packet = new DatagramPacket(buf, buf.length, address);
                socket.send(packet);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这里没有使用 DataInputStream 或 ByteArrayInputStream,因为您可以直接将 String 转换为 byte[] 并再次转换回来。

关于Java UDP数据包仅容纳5位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36136410/

相关文章:

java - Cloud Firestore 中自定义对象下的字段具有空值。如何避免这种情况?

java - Spring MVC 自定义 validator

c++ - 如何接收来自已订阅组的组播数据包?

linux - 使用 INADDR_ANY 更改 udp 服务器绑定(bind)的默认源 IP

java - 在 CentOS 5.10 上使用 Opscode 说明书安装 Tomcat6

java - 在布局中将 ID 设置为数字

java - 轻量级 Java 套接字库

python - UDP 套接字 sendto() 函数

c - C中多线程后服务器上的段错误

udp - 如何将 ZeroMQ 用于原始 UDP?