java - UDP 套接字数据报接收数据包 2x 以获取完整消息

标签 java sockets networking udp

我正在用 Java 构建一个实验性游戏服务器。

客户端发送:

length: 22\r\n
playerId: 0\r\n
\r\n\r\n
this is a test message

Java 接收消息的代码:

String message = "";

byte[] buf = new byte[20];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socketServer.receive(packet);
message += new String(buf, "UTF8");

buf = new byte[20];
packet = new DatagramPacket(buf, buf.length);
socketServer.receive(packet);
message += new String(buf, "UTF8");

它没有接收到客户端发送的 40 字节消息,它接收了 20 字节,并且在第二个 socketServer.receive(packet) 上挂起以获取新消息。

def 的原因:

This method blocks until a datagram is received. The length field of the datagram packet object contains the length of the received message. If the message is longer than the packet's length, the message is truncated.

我需要能够读取 20 个字节的消息和另外 20 个字节的消息。如何实现?

我需要这个,因为我不确定消息的长度。我想要这样的东西:

String message = "";
while (!message.contains("\r\n\r\n")) { //"\r\n\r\n" marks end of message
    byte[] buf = new byte[20];
    DatagramPacket packet = new DatagramPacket(buf, buf.length);
    socketServer.receive(packet);
    message += new String(buf, "UTF8");
}

假设消息以 \r\n\r\n 结尾,这会得到完整的消息。

它需要通过 UDP 协议(protocol)来完成。我是 Java 套接字的新手,但我认为有一些东西可以解决这个问题,只是找不到它。提前致谢。

最佳答案

UDP 并非设计用于可变长度读取 - 每个 read() [或recv() ] 将对应于单个 write() [或send() ] 在服务器上。

如果您只读取 40 字节数据包中的 20 字节,则剩余的字节将被丢弃。

您需要创建一个足够大的缓冲区来接收整个数据包(如果您的网络正确处理碎片,则最大 65536 字节)然后一次性读取整个数据包。

API 会告诉您实际收到了多少字节 - 您应该考虑对照数据包编码的值检查该数据,以确保您确实收到了整个数据包。

关于java - UDP 套接字数据报接收数据包 2x 以获取完整消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8683037/

相关文章:

java - 为什么反转 strings.xml 中字符串数组中的声明顺序会发生变化?

c - 替代 C 中的 "subclassing"结构

iphone - 我如何连接到名为 "A"的受密码保护的 wifi

java - 无法确定文件的 MIME 类型

java - Android 应用程序连接到 Web 服务失败

android - Socket EADDRINUSE(地址已被使用)

c - C 中 send()、recv() 的一些 EOF 机制

networking - Docker - 通过其公共(public) ip 访问同一台机器上的另一个容器,无需 docker 链接

regex - Chrome开发工具: any way to exclude requests whose URL matches a regex?

Java EE 应用程序由于内存消耗而在 WAS 7.0 上挂起