简体   繁体   English

Sockets:发送2Mb而不丢失数据

[英]Sockets : send 2Mb without loss of data

i am using sockets on linux, and i'd like to send a big table (more than 2 Mb) without losing any data, and fast enough to have a smooth video on the client.我在 linux 上使用 sockets,我想发送一个大表(超过 2 Mb)而不会丢失任何数据,并且速度足够快,可以在客户端上播放流畅的视频。 (what im sending is a video stream). (我发送的是视频流)。

I've tried two things:我尝试了两件事:

1°) send the entire table at once 1°) 一次发送整个表格

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

2°) send the elements one by one 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");
}

Sending the table at once is very fast, but i lose some data.一次发送表格非常快,但我丢失了一些数据。

Sending the elements one by one works fine, no data loss, but it is too slow.逐个发送元素可以正常工作,不会丢失数据,但是太慢了。

So I have 2 questions: What is the limitation of Data that can be sent in one socket (in bytes)?所以我有两个问题:可以在一个套接字中发送的数据(以字节为单位)的限制是什么? and How can I send my table quickly and without data loss?以及如何快速发送我的表而不丢失数据?

PS: My programs are supposed to comunicate in local, or in ethernet. PS:我的程序应该在本地或以太网中进行通信。 Internet comunication is not envisaged.没有设想互联网通信。

The simplest answer: use tcp socket: socket(AF_INET, SOCK_STREAM, 0) .最简单的答案:使用 tcp socket: socket(AF_INET, SOCK_STREAM, 0)

The more complicated answer: if you want to use udp, use (or invent) some protocol with delivery checking, retransmits and probably with congestion control.更复杂的答案:如果您想使用 udp,请使用(或发明)一些带有传递检查、重传和拥塞控制的协议。

Generally, UDP is a good idea for sending video stream data, as losing video data usually can be tolerated !一般来说,UDP 是发送视频 stream 数据的好主意,因为通常可以容忍丢失视频数据

If you must not lose data, consider using TCP as suggested!如果您一定不能丢失数据,请考虑按照建议使用 TCP!

The maximum packet size that can be sent via UDP depends on the hardware used in your network, there is no fixed number.通过 UDP 可以发送的最大数据包大小取决于您网络中使用的硬件,没有固定的数字。 If you need to make the best packet size, you need to implement something that is called "MTU Discorvery".如果您需要制作最佳数据包大小,则需要实现称为“MTU Discorvery”的东西。

If you can afford a good guess, make the packet size 1492.如果你猜得出来,把包大小设置为 1492。

EDIT:编辑:

If you are using Windows, consider enlarging the receiver buffer size:如果您使用的是 Windows,请考虑扩大接收缓冲区大小:

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

Network Programming is tricky and there are a lot of trade-offs you can consider.网络编程很棘手,您可以考虑很多权衡。 For example, if your server and client are both in LAN or a controlled & reliable WAN, you can use UDP.例如,如果您的服务器和客户端都在 LAN 或受控且可靠的 WAN 中,您可以使用 UDP。 This way you'll save on the overheads of TCP and also won't loose any data for most transmissions.这样,您将节省 TCP 的开销,并且不会丢失大多数传输的任何数据。

If the video is being sent over the internet and you need reliability, you must use TCP.如果通过 Internet 发送视频并且您需要可靠性,则必须使用 TCP。 If you're using TCP, then just send() all the data at once.如果您使用的是 TCP,那么只需一次send()所有数据。 TCP has built-in reliability and flow-control mechanism. TCP 具有内置的可靠性和流量控制机制。 There isn't much you can do to speed up the data transfer in this case.在这种情况下,您无法加快数据传输速度。

You can also consider using Raw sockets and implementing your own reliability and flow control.您还可以考虑使用 Raw sockets 并实现自己的可靠性和流量控制。 Else, work on your application so that it would go on fine even if there's a couple of lost video frames.否则,在您的应用程序上工作,这样即使有几个视频帧丢失,它也能正常运行 go。

Well, you didn't answer if you are using UDP or not.好吧,您没有回答是否使用 UDP。 If you are then that is your answer.如果你那么这就是你的答案。 The maximum datagram size for UDP is 64K. UDP 的最大数据报大小为 64K。 So it does not support send() 's of 2MB.所以它不支持 2MB 的send() So the first thing you are going to have to do (to continue using UDP) is break it up into chunks of 64K or less.所以你要做的第一件事(继续使用 UDP)就是把它分成 64K 或更小的块。

However, even that is suboptimal.然而,即使这样也不是最理想的。 This is because your underlying link layer likely doesn't support packets anywhere near that large.这是因为您的底层链路层可能不支持接近那么大的数据包。 UDP automatically handles this by splitting the datagram up into packet-sized transmissions. UDP 通过将数据报拆分为数据包大小的传输来自动处理此问题。 However, UDP is very simplistic.但是,UDP 非常简单。 If any one of those packets gets lost or trounced somehow, the whole datagram must be thrown away.如果这些数据包中的任何一个丢失或以某种方式被击败,则必须丢弃整个数据报。 TCP, on the other hand, would just resend the missing packet.另一方面,TCP 只会重新发送丢失的数据包。 If your UDP datagram is only a couple or three packets, this may be no big.如果您的 UDP 数据报只有几个或三个数据包,这可能没什么大不了的。 But (assuming a standard data size of 1420 or so), all your transmissions will require that there is no hiccup in 33 seperate datagrams of 47 IP packets each.但是(假设标准数据大小为 1420 左右),您的所有传输都要求在 33 个单独的数据报中没有打嗝,每个数据报有 47 个 IP 数据包。

Since you say you are on a private network, this may not matter much.由于您说您在专用网络上,因此这可能无关紧要。 If you have control over the net traffic, you could just handle this by ensuring in your protocol that nobody else is trying to use that network when these large packets are being sent.如果您可以控制网络流量,您可以通过在您的协议中确保在发送这些大数据包时没有其他人试图使用该网络来处理这个问题。 A good fast smart switch will usually take care of such problems on a LAN too, if the traffic isn't overly heavy.如果流量不是太重,一个好的快速智能交换机通常也会处理 LAN 上的此类问题。

This is why many folks have intimated that just switching to TCP may be easier for you.这就是为什么许多人暗示只切换到 TCP 对您来说可能更容易。 It handles all this in its protocol.它在其协议中处理所有这些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM