Note that there are some explanatory texts on larger screens.

plurals
  1. POAsynchronous File IO stops after a few megabytes sent
    primarykey
    data
    text
    <p>I am trying to create an asynchronous TPL file server using sockets and NetworkStream. When testing it, my browser small HTML file (1.9 KB) sends just fine, and sometimes even Javascript or CSS files that it links send to, but it won't download much more from the HTML page, including flash, images, etc. I receive no errors, including no connection errors. I can download a 96K image but that's about the limit. I set <code>Connection: Keep-Alive</code> in all response headers.</p> <p>Does anyone know why my output streaming seems to be stalling?</p> <pre><code>async Task&lt;&gt; WriteToStream(NetworkStream _networkStream, string filePath, int startingPoint = 0) { using (FileStream sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true)) { byte[] buffer = new byte[4096]; int numRead; while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0) { _networkStream.Write(buffer, 0, numRead); } } } </code></pre> <p>I also tried replacing this:</p> <pre><code>_networkStream.Write(buffer, 0, numRead); </code></pre> <p>with this:</p> <pre><code>await _networkStream.WriteAsync(buffer, 0, numRead); </code></pre> <p>and I still have the same problem. </p> <p>I'm using sockets because I can't use HttpListener or TcpListener classes since I need to access incoming UDP and TCP requests.</p> <p>I can call <code>WriteToStream()</code> with this simplified method:</p> <pre><code>private async void SendFileExample() { //This method is only for demonstration, so parameters are hardcoded. // Get info and assemble header string file = @"C:\www\webpage.html"; byte[] data = null; string responseCode = "200 OK"; string contentType = "text/html"; long dataLength = 1901; string serverName = "my Stack Overflow server is overflowing with..."; string header = string.Format("HTTP/1.1 {0}\r\n" + "Server: {1}\r\n" + "Content-Length: {2}\r\n" + "Content-Type: {3}\r\n" + "Connection: Keep-Alive\r\n" + "\r\n", responseCode, serverName, dataLength, contentType); var headerBytes = Encoding.ASCII.GetBytes(header); //send header await _networkStream.WriteAsync(headerBytes, 0, headerBytes.Length); //send payload await WriteToStream(_networkStream, file, 0); //flush networkstream await _networkStream.FlushAsync(); } </code></pre> <p>EDIT:</p> <p>Here what calls the listen loop:</p> <pre><code>_listenTask = Task.Factory.StartNew(() =&gt; ListenLoop()); </code></pre> <p>Here is the loop that spools the requests, spawning a client each time:</p> <pre><code>private async void ListenLoop() { for (; ; ) { // Wait for connection var socket = await _tcpListener.AcceptSocketAsync(); if (socket == null) break; // Got new connection, create a client handler for it var client = new Client(socket,dbInfo,frmClient); // Create a task to handle new connection Task.Factory.StartNew(client.Do); } } </code></pre> <p>Connections are handled by this method:</p> <pre><code>public async void Do() { byte[] buffer = new byte[4096]; for (; ; ) { // Read a chunk of data int bytesRead = await _networkStream.ReadAsync(buffer, 0, buffer.Length); // If Read returns with no data then the connection is closed. if (bytesRead == 0) return; // Write to buffer and process request _memoryStream.Seek(0, SeekOrigin.End); _memoryStream.Write(buffer, 0, bytesRead); bool done = ProcessHeader(); if (done) break; } } </code></pre> <p><code>ProcessHeader()</code> mostly just gets meta data like MIME types then passes the stream to the <code>WriteToStream()</code> method at the top of this post.</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.
    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