Questions about Winsock send and recv functions

Hello,

I am writing a network application that uses winsock to handle the network connections. It is my first network application, which uses a socket of type SOCK_STREAM. The protocol in use is TCP

One of the things the program is designed to do is transfer files. Currently, the file is read into a buffer that is 1024 bytes long, the buffer is sent, and this is repeated until the entire file is sent (the final buffer can be shorter).

I have heard of something called a Maximum Transmission Unit (MTU) on a network, and I was wondering if this effects my program. Do the send and receive functions (or the OS itself) automatically divide these packets or buffers I am trying to send if they are too long? The reason I am asking is because if this is the case I would be able to send most files in one call (provided there is enough ram, and only if there isn't I would have to divide them into smaller pieces)

If I am missing any important information please tell me and I will add it.

Thanks very much in advance for your time,
Ryan
Last edited on
Hi,

MTU is basically Nagle's Algorithm. Under normal circumstances you tend to send multiple 1-bit packets to the remote computer, but with the Nagle's algorithm enabled it puts all the 1-bit packets into 1-packet to decrease the amount of traffic which is being caused.
Therefore it protects the computer from having high packet's and also allows the "sender" to check if the packet reached the destination also for your condition, it will make sure if a file is sent it would be returned with either 1 or 0 : TRUE - FALSE

Whereas without Nagle's Algorithm some packets may reach some may not therefore there is a x percent chance of the file being malformed\corrupt.

Nagle's Algorithm is designed to withstand multi-threaded environment therefore it is more that possible to send multiple files without sending high amount of packets.

Check if Nagle's algorithm is enabled.
How do I check to see if it is enabled?

Also, are you saying I should be calling send() for each byte individually as opposed to calling it for a group of 1024 bytes or something like that?

Thanks,
Ryan
Hi,

To check if it enabled follow this website article:
http://b.rideekulo.us/2009/09/windows-7-nagles-algorithm-and-gaming/

I will highly recommend you to send it as it is but Nagles Algorithm will improve it a tiny bit more. So yes you are doing it good.
Thanks,

It appears to be enabled.

May I ask one more question?

I know there is a way to make a non blocking call to receive (meaning it will return if no data is waiting to be retrieved, or so I understand at least)

In my program, after a piece of the file is sent, the receiver is expected to send a one character buffer that contains either 's' or 'g' (depending whether it is the client or the server) and an 'E' followed by an error message if something goes wrong on the receivers end (this will stop the sender from sending the rest of the file).

Now the actual question, is there a way to limit the amount of time recv can wait for a packet, similar to how you can limit the time a thread will wait for a Mutex (return when either you receive or when x time has passed)?

I have been having issues where my program would often become non responsive because it will wait forever for a packet the other side has not yet been programmed to send. (in which case you currently have to close and relaunch the application)

Thanks very much,
Ryan
Hi,

Yes! It is quite easy to maintain a life time of a thread quite easily, there is a function called "WaitForSingleObject" or better "WaitForMultiple"
The Parameter(s) involved in both stated functions above are straight forward mostly the "WaitForSingleObject()".

Then in the thread if the WaitForSingleObject times out you can output information via changing a value of a error checking variable.

Normally a packet even from international distances should take just around 2 - 3 seconds, that too this is me being generous. Next point, any more than 2-3 seconds, I would consider it a error.

I will highly suggest you use WaitForSingleObject because it will can be called in a loop with ease although if you are creating mass amount of threads such as - 100,000 threads and such expect to use WaitForMultipleObject function besides the CPU usage would spike with that large thread creations at any given time.

MSDN Documentation:

WaitForSingleObject
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx

WaitForMultipleObjects
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx


GL
Currently, the file is read into a buffer that is 1024 bytes long, the buffer is sent, ... I have heard of something called a Maximum Transmission Unit (MTU) on a network
The MTU is the Maximum Transfer Unit.
See: http://en.wikipedia.org/wiki/Maximum_transmission_unit

You should send much larger blocks if you can and let TCP deal with transmission issues. If you send the Ethernet Max MTU, then each of your packets will fit exactly in an ethernet frame, optimising the use of Ethernet, but you could just send 16K or 32K blocks and let TCP deal with it, which I think is better. It's not really a Nagle issue.

is there a way to limit the amount of time recv can wait for a packet?
It's socket option. On Windows, it's SO_RCVTIMEO.
See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740476%28v=vs.85%29.aspx
Thanks both of you for your replies,

Spaceworm,
I may have been unclear sorry, I meant is there a way for a winsock function to abort a receive operation... Luckily this is only intended as a LAN program at the moment so it shouldn't need more then a few miliseconds. Thanks for your reply though, I guess I could implement another thread as the GUI currently goes unresponsive during file transfers and other communications that take a noticeable amount of time (thus windows also says the program isn't responding)

kbw,
do you mean windows / the network card will automatically divide a buffer into multiple packets if it is too long (meaning I can send most files in one call?)

Also, SO_RCVTIMEO seems to be exactly what I am looking for, thanks very much. The network portion seems to be working now, (though I found an issue with the GUI that causes a crash)

Thanks for all the help guys,
Ryan
do you mean windows / the network card will automatically divide a buffer into multiple packets if it is too long
The short answer is yes.

Are you aware of what the internet is? Unlike Ethernet, Token Ring, ATM, ..., which are all physical networks, the internet is a network of inter-connected networks. The internet runs on top of physical networks and connects across them in a seamless way; an interconnected network, hence the name. It has its own packet sizes, addressing, ...

If you want to understand it in a bit more depth, this provides a good explanation of things: http://www.firewall.cx/networking-topics/65-tcp-protocol-analysis.html

If you install Wireshark, you can see what's going thru your network adapter. http://www.wireshark.org/
Thanks for the link about TCP, I thought I knew most of how the internet worked but apparently not. This should greatly simplify and speed up my program, as I had or planned to duplicate a lot of the TCP functionality (unknowingly) as I thought all TCP did was provide error correction (by retransmit)

Thanks very much for the help both of you, I learnt a lot from this thread
Ryan
Topic archived. No new replies allowed.