Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Not seeing your code I'll have to guess.</p> <p>The reason you get a Zero window in TCP is because there is no room in the receiver's recv buffer. </p> <p>There are a number of ways this can occur. One common cause of this problem is when you are sending over a LAN or other relatively fast network connection and one computer is significantly faster than the other computer. As an extreme example, say you've got a 3Ghz computer sending as fast as possible over a Gigabit Ethernet to another machine that's running a 1Ghz cpu. Since the sender can send much faster than the receiver is able to read then the receiver's recv buffer will fill up causing the TCP stack to advertise a Zero window to the sender.</p> <p>Now this can cause problems on both the sending and receiving sides if they're not both ready to deal with this. On the sending side this can cause the send buffer to fill up and calls to send either to block or fail if you're using non-blocking I/O. On the receiving side you could be spending so much time on I/O that the application has no chance to process any of it's data and giving the appearance of being locked up.</p> <p><strong>Edit</strong></p> <p>From some of your answers and code it sounds like your app is single threaded and you're trying to do non-Blocking sends for some reason. I assume you're setting the socket to non-Blocking in some other part of the code. </p> <p>Generally, I would say that this is not a good idea. Ideally, if you're worried about your app hanging on a <a href="http://linux.die.net/man/2/send" rel="noreferrer"><code>send(2)</code></a> you should set a long timeout on the socket using <a href="http://linux.die.net/man/2/setsockopt" rel="noreferrer"><code>setsockopt</code></a> and use a separate thread for the actual sending.</p> <p>See <a href="http://linux.die.net/man/7/socket" rel="noreferrer">socket(7)</a>:</p> <blockquote> <p>SO_RCVTIMEO and SO_SNDTIMEO Specify the receiving or sending timeouts until reporting an error. The parameter is a struct timeval. If an input or output function blocks for this period of time, and data has been sent or received, the return value of that function will be the amount of data transferred; if no data has been transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be nonblocking. If the timeout is set to zero (the default) then the operation will never timeout.</p> </blockquote> <p>Your main thread can push each file descriptor into a <a href="http://www.cplusplus.com/reference/stl/queue/" rel="noreferrer"><code>queue</code></a> using say a boost mutex for queue access, then start 1 - N threads to do the actual sending using blocking I/O with send timeouts.</p> <p>Your send function should look something like this ( assuming you're setting a timeout ):</p> <pre><code>// blocking send, timeout is handled by caller reading errno on short send int doSend(int s, const void *buf, size_t dataLen) { int totalSent=0; while(totalSent != dataLen) { int bytesSent = send(s,((char *)data)+totalSent, dataLen-totalSent, MSG_NOSIGNAL); if( bytesSent &lt; 0 &amp;&amp; errno != EINTR ) break; totalSent += bytesSent; } return totalSent; } </code></pre> <p>The <code>MSG_NOSIGNAL</code> flag ensures that your application isn't killed by writing to a socket that's been closed or reset by the peer. Sometimes I/O operations are interupted by signals, and checking for <code>EINTR</code> allows you to restart the <code>send</code>.</p> <p>Generally, you should call <code>doSend</code> in a loop with chunks of data that are of <a href="http://linux.die.net/man/7/tcp" rel="noreferrer"><code>TCP_MAXSEG</code></a> size.</p> <p>On the receive side you can write a similar blocking recv function using a timeout in a separate thread.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload