views:

168

answers:

2

Hi.

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 ...

+1  A: 

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.

unwind
I've just done misprint here while posting this... In my code that call is correct ..
Nelly
+6  A: 

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.

Artelius
Seem like it is the only way to do it. Thank you
Nelly
Eh ... what? :)
Nelly
Hehe... SO is making me stay up far too late
Artelius