1

Is there any reason for a blocking call to winsock's send() function on Vista to return immediately ? It works with expected delay on XP and below. I'm wondering if this has got anything to do with auto-tuning feature of Vista. Code:

   char *pBuffer; // pointer to data
   int bytes;  // total size
   int i = 0, j=0;
   while (i < bytes)
   {
    j = send(m_sock, pBuffer+i, bytes-i, 0);
        i+=j;
   }

Thanks,
Pavan

ivymike
  • 1,511
  • 2
  • 20
  • 27
  • 1
    When you say "return immediately" do you mean without the send occurring? Kernel buffering of the send would return "really fast" which is different than "immediate". – msw Mar 25 '10 at 12:04
  • 1
    Error indications which aren't checked for (e.g. bad m_sock) would also return very fast. – msw Mar 25 '10 at 12:10
  • 1
    You're not checking for any error codes, are you? Checking that send actually did send all the data (send is allowed to break up the data into smaller chunks, so you might have to call it repeatedly) and if not, checking for SOCKET_ERROR and getting the error might throw more light on this. – Timo Geusch Mar 25 '10 at 12:26
  • clarification: Though I haven't mentioned in the code, I'm handling the error conditions (both j==SOCKET_ERROR condition and j==0 condition) properly. Also the error code is zero. I'm wondering if vista tcp stack implementation some how has set the default buffer too big (which I will check using get socket option and update here). – ivymike Mar 25 '10 at 13:30
  • @ivymike: What do you mean if Vistas TCP buffer is too big? Do you expect a specific size? It might be bigger than on XP and your send() call doesn't block. But that's not a problem as long as you have enough memory in your machine! Isn't it even better if it doesn't block? Doesn't that help your program run faster? – mmmmmmmm Mar 25 '10 at 13:42
  • @rstevens, I wanted it to block because I'm updating the status of the operation to the user using progress bar(total size/number of chunks sent) . If it returns fast the progress bar shoots up too fast :(. – ivymike Mar 25 '10 at 13:49
  • 1
    @ivymike: I would suggest to measure the time the send-loop needs. If it needed for example less than 1 second you put in a sleep(1000 - time needed by send-loop) and skip that sleep if send-loop needed more than 1s. This is just to satisfy the GUI. Even if you lower the TCP buffer size to enforce a block, the exact time it blocks depends on many other factors (i.e. network speed, ...). You should not rely on that but use something like I suggested to have a fix minimum time. – mmmmmmmm Mar 25 '10 at 13:54
  • 1
    @ivymike: Just to be not misunderstood: Do not measure the time statically and hard code the sleep! Do it in your code via something like gettimeofday() (Unix/Linux) or GetTickCount() (Windows)! – mmmmmmmm Mar 25 '10 at 14:02

2 Answers2

3

The first possibility is that send() failed and returned SOCKET_ERROR. Your code cannot detect this, you really ought to fix that.

The next possibility is that send() just doesn't block. Which is pretty normal, it will only block when there's no buffer space left in the transport sub-system. You'll have to pump several megabytes before that happens.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • nobugz, In the case of second possibility (of buffer being too big), do you think setting the buffer size on the socket will help ? I will try it anyway :) – ivymike Mar 25 '10 at 13:33
  • @ivymike: How does it HELP to make send() block? Help for what? Everyone else would be happy seeing it's send() calls not to block! – mmmmmmmm Mar 25 '10 at 13:43
1

probably the out going buffer is full. check the return code from send()

SteelBytes
  • 6,905
  • 1
  • 26
  • 28