Crixus
Crixus

Reputation: 21

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. (what im sending is a video stream).

I've tried two things :

1°) send the entire table at once

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

2°) send the elements one by one

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. Internet comunication is not envisaged.

Upvotes: 0

Views: 2417

Answers (4)

T.E.D.
T.E.D.

Reputation: 44804

Well, you didn't answer if you are using UDP or not. If you are then that is your answer. The maximum datagram size for UDP is 64K. So it does not support send()'s of 2MB. 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.

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. However, UDP is very simplistic. 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. If your UDP datagram is only a couple or three packets, this may be no big. 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.

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.

This is why many folks have intimated that just switching to TCP may be easier for you. It handles all this in its protocol.

Upvotes: 0

Raj
Raj

Reputation: 80

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. This way you'll save on the overheads of TCP and also won't loose any data for most transmissions.

If the video is being sent over the internet and you need reliability, you must use TCP. If you're using TCP, then just send() all the data at once. TCP has built-in reliability and flow-control mechanism. 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. Else, work on your application so that it would go on fine even if there's a couple of lost video frames.

Upvotes: 0

tvn
tvn

Reputation: 634

The simplest answer: use 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.

Upvotes: 1

Jens
Jens

Reputation: 6329

Generally, UDP is a good idea for sending video stream data, as losing video data usually can be tolerated!

If you must not lose data, consider using TCP as suggested!

The maximum packet size that can be sent via UDP depends on the hardware used in your network, there is no fixed number. If you need to make the best packet size, you need to implement something that is called "MTU Discorvery".

If you can afford a good guess, make the packet size 1492.

EDIT:

If you are using Windows, consider enlarging the receiver buffer size:

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

Upvotes: 1

Related Questions