我是否必须处理套接字的消息碎片?

时间:2015-04-08 21:41:51

标签: java c websocket

我目前正在使用java.net.Socket从客户端发送消息并从服务器读取消息。到目前为止,我的所有信息都相当短暂,我从来没有遇到任何问题。

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

谁是对的?

此外,我计划将来在C中创建一个客户端。 Berkeley套接字是否处理消息碎片?

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

3 个答案:

答案 0 :(得分:3)

如果您正在谈论WebSockets,您可能会混合使用不同的概念。

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

其他的是缓冲是如何工作的。您读取数据缓冲区,并且需要一个框架协议,告诉您何时有完整的“消息”(或框架)。基本上你:

  1. 读取缓冲区。
  2. 有完整的标题吗?否 - GT;转到1,是 - >继续
  3. 读取,直到头部指示的所有字节为消息 长度。
  4. 有完整的消息吗?否 - GT;转到3,是 - >继续
  5. 收益消息。
  6. 转到1。
  7. 其他不同的是WebSocket消息碎片。 WebSocket已经有一个成帧协议,消息可以分成不同的数据帧,控制帧可以与数据帧交织:https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_servers#Message_Fragmentation

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

答案 1 :(得分:1)

扩展nos所说的,TCP会将大型消息分解成更小的块,如果消息足够大, 。通常,它不是。通常情况下,您编写的数据已经分成(由您)部分,分成有意义的块,如离散消息。

关于读取/写入不同调用量的内容来自于数据的写入方式,数据传输方式以及读取方式。

如果您写入2个字节100次,然后20秒后再读取,则会说有200个字节需要读取,如果需要,您可以一次读取所有字节。如果你传递一个巨大的2mb缓冲区要写(我甚至不知道那是否可能),写出来需要更长的时间,给予阅读程序更多的机会来获得不同的读取调用。

答案 2 :(得分:1)

  

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

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