我必须为套接字处理消息碎片吗



我目前使用java.net.Socket从客户端发送消息,从服务器读取消息。到目前为止,我所有的信息都很短,我从未遇到过任何问题。

我的一个朋友注意到我没有处理消息碎片,因为数据可能是碎片,并建议我应该创建一个缓冲区来处理这个问题。我坚持TCP为我处理这个问题,但我不能百分之百确定。

谁是对的?

此外,我还计划在未来用C语言创建一个客户端。Berkeley套接字处理消息碎片吗?

详细信息:目前,在Java中,服务器创建一个套接字,并使用InputStream#read()读取消息中的第一个字节。第一个字节确定整个消息的长度,并创建一个适当长度的字节数组,调用InputStream#read(byte[])一次,并假设整个消息已被读取。

如果您谈论的是WebSockets,您可能混合了不同的概念。

一件事是TCP/IP消息碎片。

另一个问题是缓冲是如何工作的。您读取数据缓冲区,需要一个框架协议,当您有一个完整的"消息"(或框架)时,该协议会告诉您。基本上你:

  1. 读取缓冲区
  2. 有完整的标题吗?否->转到1,是->继续
  3. 读取,直到具有头指示为消息的所有字节长度
  4. 有完整的消息吗?否->转到3,是->继续
  5. Yield消息
  6. 转到1

另一个不同的是WebSocket消息碎片。WebSocket已经有了一个成帧协议,消息可以在不同的数据帧中分割,控制帧可以与数据帧交织:https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_servers#Message_Fragmentation

如果您正在编写WebSocket客户端或服务器,则必须为这种情况做好准备。

根据nos的说法,TCP将把大消息分解成更小的块,如果消息足够大。通常情况下,情况并非如此。通常,您编写的数据已经(由您)分成多个部分,分成有意义的块,如离散消息。

读取/写入需要不同数量的调用,这取决于数据是如何写入的,它是如何在线路上传输的,以及你是如何读取的

如果你写2个字节100次,20秒后再读,它会说有200个字节要读,如果你想的话,你可以一次全部读。如果你通过一个巨大的2mb缓冲区来写(我甚至不知道这是否可能),写出来需要更长的时间,这给了阅读程序更多的机会来获得不同的阅读调用。

详细信息:目前,在Java中,服务器创建一个套接字,并使用InputStream#read()读取消息中的第一个字节。第一个字节确定整个消息的长度,并创建一个适当长度的字节数组,调用InputStream#read(byte[])一次,并假设整个消息已被读取。

那行不通。看一下InputStream.read(byte[]).的合同它没有义务传输超过一个字节。正确的技术是读取长度字节,然后使用有义务填充缓冲区的DataInputStream.readFully(),

最新更新