套接字:发送2Mb而不丢失数据

时间:2011-06-01 13:37:56

标签: c++ sockets

我在linux上使用套接字,我想发送一个大表(超过2 Mb)而不丢失任何数据,并且足够快以在客户端上获得流畅的视频。 (发送的是视频流)。

我尝试了两件事:

1°)立即发送整个表

socketError = send(newsockfd,(char*) DataTab,sizeof(DataTab),0);
if (socketError < 0)
    error("ERROR server writing to socket");

2°)逐个发送元素

for (int i=0; i<nbelem; i++) // nbelem is greater than 600'000
{
    socketError = send(newsockfd,(char*) &DataTab[i],sizeof(&DataTab[i]),0);
    if (socketError < 0)
    error("ERROR server writing to socket");
}

立即发送表格非常快,但我丢失了一些数据。

逐个发送元素可以正常工作,没有数据丢失,但速度太慢。

所以我有两个问题:可以在一个套接字中发送的数据的限制是什么(以字节为单位)?如何快速发送表格而不丢失数据?

PS:我的程序应该在本地或以太网中进行通信。没有设想互联网通信。

4 个答案:

答案 0 :(得分:2)

最简单的答案:使用tcp socket:socket(AF_INET, SOCK_STREAM, 0)

更复杂的答案:如果你想使用udp,请使用(或发明)一些协议,包括传递检查,重新传输以及可能具有拥塞控制。

答案 1 :(得分:1)

通常,UDP是发送视频流数据的好主意,因为通常可以容忍丢失视频数据

如果您不能丢失数据,请考虑按建议使用TCP!

可以通过UDP发送的最大数据包大小取决于网络中使用的硬件,没有固定的数字。如果您需要制作最佳数据包大小,则需要实现一种称为“MTU Discorvery”的东西。

如果你能负担得起,请将数据包大小改为1492。

编辑:

如果您使用的是Windows,请考虑放大接收器缓冲区大小:

int bufferSize = 64 * 1024;  // 64k
setsockopt( socket, SOL_SOCKET, SO_RCVBUF, (char *) & bufferSize );

答案 2 :(得分:0)

网络编程很棘手,你可以考虑很多权衡。例如,如果您的服务器和客户端都在LAN中或受控制的&amp;可靠的WAN,您可以使用UDP。通过这种方式,您可以节省TCP的开销,并且不会丢失大多数传输的任何数据。

如果视频是通过互联网发送的,并且您需要可靠性,则必须使用TCP。如果您正在使用TCP,那么只需send()一次所有数据。 TCP具有内置的可靠性和流量控制机制。在这种情况下,您无法加快数据传输速度。

您还可以考虑使用Raw套接字并实现自己的可靠性和流量控制。否则,请处理您的应用程序,以便即使有几个丢失的视频帧也能正常运行。

答案 3 :(得分:0)

好吧,如果你使用的是UDP,你没有回答。如果您 那么这就是您的答案。 UDP的最大数据报大小为64K。所以它不支持2MB的send()。因此,您要做的第一件事(继续使用UDP)是将其分解为64K或更少的块。

然而,即使这样也不是最理想的。这是因为您的基础链接层可能不支持那么大的数据包。 UDP通过将数据报分成数据包大小的传输来自动处理此问题。但是,UDP非常简单。如果这些数据包中的任何一个丢失或以某种方式被破坏,则必须丢弃整个数据报。另一方面,TCP只会重新发送丢失的数据包。如果您的UDP数据报只有几个或三个数据包,这可能不大。但是(假设标准数据大小为1420左右),所有传输都要求33个单独的数据报中没有打嗝,每个数据报包含47个IP数据包。

既然你说你在私人网络上,这可能并不重要。如果您可以控制网络流量,则可以通过在协议中确保在发送这些大数据包时没有其他人尝试使用该网络来处理此问题。如果流量不是太大,一个好的快速智能交换机通常也会在局域网上处理这些问题。

这就是为什么很多人都暗示只是切换到TCP可能对你来说更容易。它在协议中处理所有这些。