Question

I'm using unix scoket for data transferring (SOCK_STREAM mode)

I need to send a string of more than 100k chars. Firstly, I send length of a string - it's sizeof(int) bytes.

length = strlen(s)
send(sd, length, sizeof(int))

Then I send the whole string

bytesSend = send(sd, s, length)

but for my surprise "bytesSend" is less than "length".

Note, that this works fine when I send not so big strings. May be there exist some limitations for system call "send" that I've been missing ...

Was it helpful?

Solution

The send system call is supposed to be fast, because the program may have other things useful things to do. Certainly you do not want to wait for the data to be sent out and the other computer to send a reply - that would lead to terrible throughput.

So, all send really does is queues some data for sending and returns control to the program. The kernel could copy the entire message into kernel memory, but this would consume a lot of kernel memory (not good).

Instead, the kernel only queues as much of the message as is reasonable. It is the program's responsibility to re-attempt sending of the remaining data.

In your case, use a loop to send the data that did not get sent the first time.

while(length > 0) {
    bytesSent = send(sd, s, length);
    if (bytesSent == 0)
        break; //socket probably closed
    else if (bytesSent < 0)
        break; //handle errors appropriately
    s += bytesSent;
    length -= bytesSent;
}

At the receiving end you will likely need to do the same thing.

OTHER TIPS

Your initial send() call is wrong. You need to pass send() the address of the data, i.e.:

bytesSend = send(sd, &length, sizeof(int))

Also, this runs into some classical risks, with endianness, size of int on various platforms, et cetera.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top