从TCP套接字接收数据包数据包?

时间:2011-06-07 10:21:39

标签: c++ c sockets tcp

我有一个tcp套接字,我在其上接收视频流。我希望从socket接收数据包,以便我可以删除数据包标头并保留唯一的流数据。我怎么能这样做?

任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:15)

你做不到。 TCP不适用于数据包/消息等。TCP适用于字节。你得到一个字节流。问题是,无法保证每次从套接字读取时都会得到的字节数。通常的方法来处理这个问题:

  • 当您要发送“数据包”时,首先包括长度
  • 当您从套接字中读取内容时,请确保至少读取该长度

您的留言可能是:

|Message Length:4bytes|Additional header Information:whatever1|Message Data:whatever2|

您需要做的是读取4个字节,然后读取这4个字节告诉您的内容。然后,您将能够剥离标题并获取数据。

答案 1 :(得分:3)

TCP是一种流媒体协议。您获得没有消息边界的字节。解决方案是缓冲所有读取并从缓冲区中提取/处理完整的视频数据包。

算法:

  1. 初始化一个空缓冲区。
  2. 检查缓冲区是否有完整的数据包。
  3. 如果找到,请从缓冲区的开头删除完整的数据包并进行处理。
  4. 如果找不到,请将recv()中的数据附加到缓冲区,然后转到#2。
  5. 视频流协议应定义“完整数据包”包含的内容。

答案 2 :(得分:2)

TCP是一种流协议,它不保证当您调用套接字读取功能时,您将收到一个完整的数据包。 UDP或SCTP是面向数据包的协议,并保证这一点。对于TCP,您可以一次获取数据包的一部分或少量数据包。您必须在TCP和片段/碎片整理消息之上构建自己的应用程序协议。

答案 3 :(得分:2)

正如其他人所提到的,TCP是一种流媒体协议。这意味着从API的角度来看,没有“数据包”的概念。作为用户,您可以期待的只是一个数据流。

在内部,TCP会将流分解为可以放入IP数据包的段。这些数据包将与控制数据一起通过IP发送到远程端。远程端将接收这些IP数据包。它可能会丢弃某些IP数据包(在重复的情况下),重新排序数据包或保留数据,直到更早的数据包到达。所有这些都是TCP内部的意思,“TCP数据包”的概念毫无意义。

您可能可以使用原始套接字来接收原始IP数据包,但这意味着您必须重新实现大部分TCP堆栈(如发送ACK和调整窗口大小)以使远程端正确执行。你不想这样做。

另一方面,UDP是数据报协议。这意味着用户可以了解数据是如何通过网络发送的。如果数据包或数据报的概念对您很重要,则需要在UDP之上构建自己的协议。

答案 4 :(得分:1)

您对此方法非常肯定吗?在我看来,这些“预处理”将为系统带来额外的开销。当然,这是由较低层(阅读OSI模型)处理的,因此不容易改变。请注意,大多数现有的流媒体协议已针对最佳性能进行了优化。