tags:

views:

87

answers:

2

Hi all!

I would like to know: when programming in C using a socket (AF_UNIX) is there any limit (in bytes) when sending or receiving to or from a socket?

Thank you!

—Albé

+2  A: 

You can change the read and write buffers for each individual socket connection using setsockopt (SO_SNDBUF and SO_RCVBUF).

The default and maximum sizes are platform dependent.

Furthermore, if you provide a larger user-side buffer for each individual read e.g. with recv.

And if you use several recvs in sequence, you can read an infinite amount of bytes over a connection, it'll just take infinitely long.

Will
+1 straight to the point answer
Iulian Şerbănoiu
A: 

sockets behavior is implementation is dependent. In general when you send() there is no guarantee how many bytes will get pushed onto the socket. Since the kernel controls this it can be any number, generally in the range of 1500 or less. So what you have to do is check the send() return code and keep pushing data onto the socket until you are done. This example assumes that you already set the socket to non-blocking with:

 fcntl(s, F_SETFL, O_NONBLOCK);


int sendall(int s, char *buf, int *len)
{
        int total = 0;        /* how many bytes we've sent */
        int bytesleft = *len; /* how many we have left to send */
        int n=0;
        int retries=0;
        struct timespec tp={0,500};

        while(total < *len) 
        {
                n = send(s, buf+total, bytesleft, 0);
                if (n == -1)
                {
                   /* handle errors here, 
                      plus check for EWOULDBLOCK 
                      and then nanosleep()
                   */
                }
                total += n;
                bytesleft -= n;
        }

To answer your question - no there is no limit, you just cannot send all of your data with one send() call.

jim mcnamara
Why set it to non-blocking and then iterate over it in a tight loop? Seems a contradiction.
Will
Note the EWOULDBLOCK comment and the timepsec declaration. That implies waiting on a blocking socket for a small amount of time.I did not show it, you are correct, but is not definitely not intended as tight loop. I trashed 40 lines of the function to put it in here. Largely because it had some Solaris specific socket code. Posting system specific code is bad idea IMO, unless it is explicitly asked for as part of the question.
jim mcnamara
Hmm, you are wrong about **a)** 1500 bytes - you assume ethernet packet size, but it's actually socket *send buffer* that is filled when you call `send(2)`, which is different on different OS-es but usually bigger then one frame (and you are forgetting about IP and TCP or UDP headers in your calculations); **b)** non-blocking and nanosleep - you are just emulating a blocking send but not letting the OS wake you up when send-buffer space becomes available. *Get rid of this code* and just use `/dev/poll` on Solaris.
Nikolai N Fetissov