Note that there are some explanatory texts on larger screens.

plurals
  1. POSocket.BeginSend does not complete synchronously despite plenty of buffer space
    primarykey
    data
    text
    <p>Why does <code>Socket.BeginSend</code> go asynchronous so quickly and so unpredictably? I know it's supposed to be asynchronous, but it can also complete immediately, in which case <code>IAsyncResult.CompletedSynchronously</code> is set. I would expect <code>CompletedSynchronously</code> to be true until the 8KB send buffer is filled up. The test case below (cleanup code stripped for brevity) demonstrates that <code>BeginSend</code> goes asynchronous on (typically) 3rd iteration after buffering only 6 bytes of data:</p> <pre class="lang-cs prettyprint-override"><code>TcpListener listener = new TcpListener(IPAddress.Any, 35001); listener.Start(); Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) client.Connect(new IPEndPoint(IPAddress.Loopback, 35001)); Socket server = listener.AcceptSocket()) for (int i = 1; i &lt;= 10; ++i) { bool sent = false; IAsyncResult result = client.BeginSend(new byte[] { 1, 2, 3 }, 0, 3, SocketFlags.None, r =&gt; sent = true, null); Assert.IsTrue(result.CompletedSynchronously, // fails typ. on 3rd iteration String.Format("Asynchronous on iteration {0}", i)); Assert.IsTrue(sent); client.EndSend(result); } </code></pre> <p>The exact iteration when it goes asynchronous is somewhat random. When process starts, it's 3. Afterwards it's 1 for all new sockets. I've seen other numbers sporadically. I know the 8KB socket send buffer is there, because <code>Socket.Send</code> (with <code>Socket.Blocking = false</code>) stops at about 8KB.</p> <p>Method <code>Socket.SendAsync</code> behaves similarly except it always completes asynchronously (i.e. no attempt at direct buffer write). See my <a href="https://stackoverflow.com/questions/14345297/when-does-socket-sendasync-complete-synchronously">related question about Socket.SendAsync</a>.</p> <p>I need <code>BeginSend</code> to be mostly synchronous for performance reasons (asynchronous callbacks are slower). Not to mention the unpredictability ruins unit tests and benchmarks for my low-level communication code.</p>
    singulars
    1. This table or related slice is empty.
    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.
 

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