views:

807

answers:

5

Hi all,

I am looking to send a large message > 1 MB through the windows sockets send api . Is there a efficient way to do this , i do not want to loop and then send the data in chunks . I have read somewhere that you can increase the socket buffer size and that could help . Could anyone please elobrate on this . Any help is appreciated

+1  A: 

Why don't you want to send it in chunks?

That's the way to do it in 99% of the cases.

Assaf Lavie
well the application is a legacy app , i do not want to change the code a lot . that's why i was looking for something with minimum code changes .
It's not necessary to include all the code inline. Write a function for sending a huge buffer and let it send in chunks, then call this function. This way you only change the original code a little.
sharptooth
A: 

The windows sockets subsystem is not oblidged to send the whole buffer you provide anyway. You can't force it since some network level protocols have an upper limit for the packet size.

sharptooth
A: 

What makes you think that sending in chunks is inefficient? The OS is likely to chunk large "send" calls anyway, and may coalesce small ones.

Likewise on the receiving side the client should be looping anyway as there's no guarantee of getting all the data in one go.

Jon Skeet
A: 

You should, and in fact must loop to send the data in chunks.

As explained in Beej's networking guide:

"send() returns the number of bytes actually sent out—this might be less than the number you told it to send! See, sometimes you tell it to send a whole gob of data and it just can't handle it. It'll fire off as much of the data as it can, and trust you to send the rest later."

This implies that even if you set the packet size to 1MB, the send() function may not send all of it, and you are forced to loop until the total number of bytes sent by your calls to send() total the number of bytes you are trying to send. In fact, the greater the size of the packet, the more likely it is that send() will not send it all.

Aside from all that, you don't want to send 1MB packets because if they get lost, you will have to transmit the entire 1MB packet again, whereas if you lost a 1K packet, retransmitting it is not a big deal.

In summary, you will have to loop your send() calls, and the receiver will even have to loop their recv() calls too. You will likely need to prepend a small header to each packet to tell the receiver how many bytes are being sent so the receiver can loop the appropriate number of times.

I suggest you take a look at Beej's network guide for more detailed info about send() and recv() and how to deal with this problem. It can be found at http://beej.us/guide/bgnet/output/print/bgnet_USLetter.pdf

MahlerFive
Thanks ... that was helpful
A: 

As a practical matter, you can actually allocate a large buffer and send in one call using Winsock. If you are not messing with socket buffer sizes, the buffer will generally be copied into kernel mode for sending anyway.

There is a theoretical possibility that it will return without sending everything, however, so you really should loop for correctness. The chunks you send should, however, be large (64k or the ballpark) to avoid repeated kernel transitions.

a_mole