Modify default value of socket buffer sizes in windows - c

In the socket programming, SO_SNDBUF and SO_RCVBUF will have the default value as the 8192 bytes when the size of RAM is greater than 19MB.
Now, I want to change the socket buffer sizes for my sockets.I know that one way is by setsockopt. But, I want to apply changes to the system default, and be able to use the modified value of the socket buffers for all the sockets I create in the system. Please let me know where do I make the configuration changes in windows platform?

Here there is a description of how it works:
http://smallvoid.com/article/winnt-winsock-buffer.html
And the solution should be:
[HKEY_LOCAL_MACHINE \SYSTEM \CurrentControlSet \Services \Afd \Parameters]
DefaultReceiveWindow = 16384
DefaultSendWindow = 16384

Related

Querying remaining socket send buffer size in C?

I am trying to solve the problem of being able to read from one socket and then write to another socket without blocking and without buffering for cases where I cannot use splice().
As a first pass solution what I have in mind is to query the remaining size of the send buffer on the write socket, read that much from the reading socket, then write that much to the write socket knowing we can't block.
I have found someone claim at https://stackoverflow.com/a/9982492/4598583 that to query the remaining buffer size you can do the following:
getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &send_buf, &optlen);
However, I cannot find a reference to whether SO_SNDBUF will return the maximum buffer size or the remaining buffer size.
Can anyone confirm if querying the remaining (not maximum) buffer size is possible?
Alternatively, when a write socket indicates that that socket is writable (via poll() or some other mechanism) is there a minimum size of data defined anywhere that you can write without blocking or truncation in this case?
SO_SNDBUF don't give you the remaining size of send buffer, but the maximum size of it. This should be the max buffer that the OS can send each time, or max send witout blocking. So it should fit anyway your need.
From Linux Manual:
SO_SNDBUF
Sets or gets the maximum socket send buffer in bytes. The
kernel doubles this value (to allow space for bookkeeping
overhead) when it is set using setsockopt(2), and this doubled
value is returned by getsockopt(2). The default value is set
by the /proc/sys/net/core/wmem_default file and the maximum
allowed value is set by the /proc/sys/net/core/wmem_max file.
The minimum (doubled) value for this option is 2048.

What is the default size of datagram queue length in Unix Domain Sockets (AF_UNIX)? Is it configurable?

I know the maximum length of a datagram queue length can be found using
"cat /proc/sys/net/unix/max_dgram_qlen".
I wanted to know how to find the default value that is set on boot up (like in case of the /proc/sys/net/core/wmem_default for the send buffer size).
Is it possible to increase the value of max_dgram_qlen? What is the upper limit of the same?
My kernel version is 2.6.27.7. I'm new to Unix Domain Socket programming (AF_UNIX).
Thanks in advance for any comments / solutions!
The previous answers/comments failed to understand that the OP was talking about maximum queue length in datagrams (max_dram_qlen) and not in bytes. The OS provides settings for both sizes.
You can set max_dgram_qlen using the following command:
sysctl net.unix.max_dgram_qlen=128
You may need to run with sudo and you may also need to put double quotes around max_dgram_qlen=128 depending on your shell.
Also, see What's the practical limit on the size of single packet transmitted over domain socket?.
man unix(7):
The SO_SNDBUF socket option does have an effect for UNIX domain sockets, but the SO_RCVBUF option does not. For datagram sockets, the SO_SNDBUF value imposes an upper limit on the size of outgoing datagrams. This limit is calculated as the doubled (see socket(7)) option value less 32 bytes used for overhead.

recommended chunk size for sending in C?

I have a server which needs to transfer a large amount of data (~1-2 gigs) per request. What is the recommended amount of data that each call to send should have? Does it matter?
The TCP/IP stack takes care of not sending packets larger than the PATH MTU, and you would have to work rather hard to make it send packets smaller than the MTU, in ways that wouldn't help throughput: and there is no way of dsicovering what the path PTU actually is for any given connection. So leave all consideration of the path MTU out of it.
You can and should make every send() as big as possible.
Your packet size is constraint by the Maximum Transfer Unit (MTU) of the protocol. If you send a packet bigger than the MTU then you get packet fragmentation.
You can do some math: http://www.speedguide.net/articles/mtu-what-difference-does-it-make--111
More References: http://en.wikipedia.org/wiki/Maximum_transmission_unit
But ultimately my suggestion is that if you aim for good enough and just let the os network layer do its work, unless you are programming raw sockets or passing some funky options, is pretty common that the os will have a network buffer and will try to do its best.
Considering this last option then the socket.send() is nothing else than a memory transfer from your user process memory to the kernel's private memory. The rule of thumb is to not exceed the virtual memory page size http://en.wikipedia.org/wiki/Page_(computer_memory) that is usually 4KB.

how to send UDP datagram larger than system buffer?

can any body here tell me how to send datagram larger than system buffer supplied to UDP socket in order to test the MSG_TRANC in C
and how i can get the size of the socket buffer ?
You could always increase the buffer size with the setsockopt function using the SO_SNDBUF flag.
Otherwise send (or sendto) will normally block.
However, I would recommend you to try and rework your protocol so the packets fit inside the send buffer. You can always reassemble the packages when received (if you have proper sequencing of them).
What do you mean or want to to do?
I hope you read http://en.wikipedia.org/wiki/User_Datagram_Protocol
Are you attempting to send a datagram with total length greater than single packet size? Or is your send buffer used in building a packet too small?

Sending TCP frames of fixed length

I need to send some data over the subnet with fixed non-standard MTU (for example, 1560) using TCP.
All the Ethernet frames transfered through this subnet should be manually padded with 0's, if the frame's length is less than MTU.
So, the data size should be
(1560 - sizeof( IP header ) - sizeof( TCP header ) ).
This is the way I am going to do it:
I set the TCP_CORK option to decrease the fragmenting of data. It is not reliable, because there is 200 millisecond ceiling, but it works.
I know size of IP header (20 bytes), so data length should be equal to (1540 - sizeof( TCP header )).
That's the problem. I don't know the TCP header size. The size of it's "Options" field is floating.
So, the question is: how to get the size of TCP header? Or maybe there is some way to send TCP frames with headers of fixed length?
Trying to control the size of frames when using TCP from the user application is wrong. You are working at the wrong abstraction level. It's also impossible.
What you should be doing is either consider replacing TCP with something else (UDP?) or, less likely, but possible, rewrite your Ethernet driver to set the non standard MTU and do the padding you need.
This isn't possible using the TCP stack of the host simply because a TCP stack that follows RFC 793 isn't supposed to offer this kind of access to an application.
That is, there isn't (and there shouldn't be) a way to influence what the lower layers do with your data. Of course, there are ways to influence what TCP does (Nagle for example) but that is against the spirit of the protocol. TCP should be used for what it's best at: transferring a continuous, ordered stream of bytes. Nothing more, nothing less. No messages, packets, frames.
If after all you do need to control such details, you need to look at lower-level APIs. You could use SOCK_RAW and PF_PACKET.
Packet sockets are used to receive or
send raw packets at the device driver
(OSI Layer 2) level.
#gby mentioned UDP and that is (partially) a good idea: UDP has a fixed size. But keep in mind that you will have to deal with IP fragmentation (or use IP_DONTFRAG).
In addition to my comments below the OP's question, this quote from the original RFC outlining how to send TCP/IP over ethernet is relevant:
RFC 894 (emphasis mine):
If necessary, the data field should be padded (with octets of zero) to meet the Ethernet minimum frame size.
If they wanted all ethernet frames to be at maximum size, they would have said so. They did not.
Maybe what was meant by padding is that the TCP header padding to align it on 32 bits should be all zeros : http://freesoft.org/CIE/Course/Section4/8.htm

Resources