Click here to Skip to main content
15,887,256 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
XML
Hi All
I have to major the HTTP traffic via proxy, When I try to upload any image or any files  it goes to hang or block. As my observation the StreamReader make it block and it is bind with NetworkStream.
   while (totalBytesRead < contentLen && (bytesRead = clientStreamReader.ReadBlock(postBuffer, 0, contentLen)) > 0)
                    {
                        totalBytesRead += bytesRead;
                        sw.Write(postBuffer, 0, bytesRead);
                        Console.Write(postBuffer, 0, bytesRead);
                    }
Can you help me why it block or Hang?


C#
private  void ProxyProcessing(TcpClient client)
        {
         //   client.ReceiveTimeout = 150000;
          //  client.SendTimeout = 150000;
            Stream mainStream = client.GetStream();
            Stream outStream = mainStream; 
            SslStream sslStream = null;
            StreamReader clientStreamReader = new StreamReader(mainStream);
           
            MemoryStream cacheStream = null;            
      
            try
            {
                //read the first line HTTP command
                String httpCmd = clientStreamReader.ReadLine();
                if (String.IsNullOrEmpty(httpCmd))
                {
                    clientStreamReader.Close();
                    mainStream.Close();
                    return;
                }
                //break up the line into three components
                String[] splitBuffer = httpCmd.Split(spaceSplit, 3);

                String method = splitBuffer[0];
                String remoteUri = splitBuffer[1];
                Version version = new Version(1, 1);

                HttpWebRequest webReq;
                HttpWebResponse response = null;
                if (splitBuffer[0].ToUpper() == "CONNECT")
                {
                    clientStreamReader.Close();
                    mainStream.Close();
                    return;
                }

                //construct the web request that we are going to issue on behalf of the client.
                webReq = (HttpWebRequest)HttpWebRequest.Create(remoteUri);
                webReq.Method = method;
                webReq.ProtocolVersion = version;

                //read the request headers from the client and copy them to our request
                int contentLen = ReadRequestHeaders(clientStreamReader, webReq);
                
                webReq.Proxy = null;
                webReq.KeepAlive = false;
                webReq.AllowAutoRedirect = false;
                webReq.AutomaticDecompression = DecompressionMethods.None;
        
              
                if (method.ToUpper() == "POST")
                {
                    char[] postBuffer = new char[contentLen];
                    int bytesRead;
                    int totalBytesRead = 0;
                    StreamWriter sw = new StreamWriter(webReq.GetRequestStream());

                    while (totalBytesRead < contentLen && (bytesRead = clientStreamReader.ReadBlock(postBuffer, 0, contentLen)) > 0)
                    {                       
                        totalBytesRead += bytesRead;
                        sw.Write(postBuffer, 0, bytesRead);                        
                        Console.Write(postBuffer, 0, bytesRead);
                    }    
                    sw.Close();
                }
                    
                   webReq.Timeout = 15000;

                    try
                    {
                        response = (HttpWebResponse)webReq.GetResponse();
                    }
                    catch (WebException webEx)
                    {
                        response = webEx.Response as HttpWebResponse;
                    }
                    if (response != null)
                    {
                        List<Tuple<String,String>> responseHeaders = ProcessResponse(response);
                        StreamWriter myResponseWriter = new StreamWriter(outStream);
                        Stream responseStream = response.GetResponseStream();
                        try
                        {
                            //send the response status and response headers
                            WriteResponseStatus(response.StatusCode,response.StatusDescription, myResponseWriter);
                            WriteResponseHeaders(myResponseWriter, responseHeaders);

                            Byte[] buffer;
                            if (response.ContentLength > 0)
                                buffer = new Byte[response.ContentLength];
                            else
                                buffer = new Byte[BUFFER_SIZE];

                            int bytesRead;

                            while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                if (cacheStream != null)
                                    cacheStream.Write(buffer, 0, bytesRead);
                                outStream.Write(buffer, 0, bytesRead);                             
                            }

                            responseStream.Close();                         

                            outStream.Flush();
                         
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        finally
                        {
                            responseStream.Close();
                            response.Close();
                            myResponseWriter.Close();
                        }
                    }                
              
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                clientStreamReader.Close();
                mainStream.Close();
                if (sslStream != null)
                    sslStream.Close();
                outStream.Close();              
            }
        }
Posted

1 solution

This is a blocking code indeed, and this blocking is efficient in terms of performance; the thread is put to wait state and will be waken up when data arrives. This is a good thing, not bad. That's why all the communications should be done in a separate thread.

—SA
 
Share this answer
 
Comments
GAJERA 24-May-13 0:45am    
ok,Why any images or document are not uploaded?
Sergey Alexandrovich Kryukov 24-May-13 1:06am    
You can run your code under the debugger and figure this out. Can you do it by yourself?
—SA
GAJERA 24-May-13 1:15am    
Can you suggest the other way to read networkStream?
Sergey Alexandrovich Kryukov 24-May-13 1:23am    
Why? This is one of the stream classes. All stream classes are read in exact same way. This is a good thing, not bad. Your problem is that you don't want to embrace the idea of blocking calls, which is very efficient. You just need to block the thread and work in other threads in parallel. This is much better then async. API, because you develop your methods of thread synchronization and use them again and again. Unlike async. API, these techniques are not application-specific.
—SA
GAJERA 24-May-13 1:31am    
When i read the request http header ,the "content length:24565",but when read StreamReader, ReadBlock API return 23562.Means the less then original one.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900