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

时间:2011-12-30 19:09:41

标签: 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的理由:

  

此方法将一直阻塞,直到收到数据报。长度字段   数据报包对象包含接收的长度   信息。如果消息长于数据包的长度,则   消息被截断。

我需要能够读取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协议完成。我是Java中的套接字新手,但我认为有一些东西可以找到它,但是找不到它。提前致谢。

2 个答案:

答案 0 :(得分:2)

如果写入40个字节,则应该接收40个字节。如果你写了40个字节,而你的缓冲区只有20个,那么你将丢失20个字节。

问:那么为什么不让你的缓冲区为256字节(例如),并读取你得到的任何东西?

问:如果您需要"消息"分两部分...然后为什么不发送两条消息?

答案 1 :(得分:2)

UDP不适用于可变长度读取 - 每个read() [或recv()]将对应于服务器上的单个write() [或send()]。 / p>

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

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

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