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

问题描述 投票:0回答:5

我有一个 TCP 套接字,可以在其上接收视频流。我想从套接字接收数据包,以便我可以删除数据包标头并保留唯一的流数据。我该怎么办??

任何帮助将不胜感激。

c++ c sockets tcp
5个回答
20
投票

你不能。

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

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

您的信息可能是:

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

然后您要做的就是读取 4 个字节,然后然后 读取这 4 个字节告诉您的内容。然后您就可以剥离标头并获取数据。


7
投票

正如其他人提到的,TCP 是一种流协议。这意味着从 API 的角度来看,不存在“数据包”的概念。作为用户,您所期望的只是数据流。

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

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

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


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

算法:

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


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


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

© www.soinside.com 2019 - 2024. All rights reserved.