简体   繁体   English

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

[英]UDP socket Datagram receive packet 2x to get full message

I am building an experimental game server in Java . 我正在用Java构建一个实验性游戏服务器。

Client sends: 客户发送:

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

Java code to receive 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");

This doesn't receive 40 bytes of the message sent by the client, it receives 20 bytes and on the second socketServer.receive(packet) it hangs for a new message. 这不接收客户端发送的40个字节的消息,它接收20个字节,而第二个socketServer.receive(packet)则挂起新消息。

Reason by def: 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. 如果消息长于数据包的长度,则消息将被截断。

I need to be able to read 20 bytes of the message and another 20 bytes of the message. 我需要能够读取20个字节的消息和另外20个字节的消息。 How can this be achieved? 怎么能实现这一目标?

I need this because I'm not sure how long the message will be. 我需要这个,因为我不确定消息会持续多久。 I want something like this: 我想要这样的东西:

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");
}

This gets full message assuming message ends with \\r\\n\\r\\n . 假设消息以\\r\\n\\r\\n结尾,则获取完整消息。

It needs to be done over the UDP protocol. 它需要通过UDP协议完成。 I am new to sockets in Java but I assume there is something for this, just cannot find it. 我是Java套接字的新手,但我认为有一些东西,只是找不到它。 Thanks in advance. 提前致谢。

If you write 40 bytes, you should receive 40 bytes. 如果写入40个字节,则应该接收40个字节。 If you write 40 bytes and your buffer is only 20, then you'll lose 20 bytes. 如果你写40个字节而你的缓冲区只有20个,那么你将丢失20个字节。

Q: So why not make your buffer 256 bytes (for example), and read whatever you get? 问:那么为什么不让你的缓冲区为256字节(例如),并读取你得到的任何东西?

Q: If you need the "message" to arrive in two parts ... then why not just send two messages? 问:如果您需要“消息”分两部分...那么为什么不发送两条消息?

UDP isn't designed for variable length reads - each read() [or recv() ] will correspond to a single write() [or send() ] on the server. UDP不是为可变长度读取而设计的 - 每个read() [或recv() ]将对应于服务器上的单个write() [或send() ]。

If you only read 20 bytes of a 40 byte packet the remaining bytes will be discarded. 如果只读取40字节数据包的20个字节,则将丢弃剩余的字节。

You need to create a buffer large enough to receive the entire packet (max 65536 bytes if your network handles fragmentation properly) and then read the entire packet in one go. 您需要创建一个足够大的缓冲区来接收整个数据包(如果您的网络正确处理碎片,则最多65536个字节)然后一次读取整个数据包。

The API will tell you how many bytes were actually received - you should consider checking that against the value encoded within the packet to ensure that you did receive the entire packet. 该API会告诉你有多少字节实际上收到的-你应该考虑检查,对在包的编码值,以确保您确实收到整个数据包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM