我有一个tcp套接字,我在其上接收视频流。我希望从socket接收数据包,以便我可以删除数据包标头并保留唯一的流数据。我怎么能这样做?
任何帮助将不胜感激。
答案 0 :(得分:15)
你做不到。 TCP
不适用于数据包/消息等。TCP
适用于字节。你得到一个字节流。问题是,无法保证每次从套接字读取时都会得到的字节数。通常的方法来处理这个问题:
您的留言可能是:
|Message Length:4bytes|Additional header Information:whatever1|Message Data:whatever2|
您需要做的是读取4个字节,然后读取这4个字节告诉您的内容。然后,您将能够剥离标题并获取数据。
答案 1 :(得分:3)
TCP是一种流媒体协议。您获得没有消息边界的字节。解决方案是缓冲所有读取并从缓冲区中提取/处理完整的视频数据包。
算法:
recv()
中的数据附加到缓冲区,然后转到#2。视频流协议应定义“完整数据包”包含的内容。
答案 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模型)处理的,因此不容易改变。请注意,大多数现有的流媒体协议已针对最佳性能进行了优化。