CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Jul 2009
    Location
    London
    Posts
    13

    [RESOLVED] Stream closed while writing

    Hi there, this is - I think - my third post on this subject, which means I was still not able to implement my proxy server.
    For the people that did not read my other posts, I am trying to use the .NET framework to create a proxy server that intercepts all requests to a certain port and redirects them to an indicated address (indicates by me), appending all the correct credentials (and the purpose of all this thing is to handle the authentication, so that the clients dont need to worry about it). I created a class to implement the server, and I call it like this, inside a thread.

    Code:
    				m_prx = new ProxyServer(this);
    				System.Threading.Thread proxythread = new System.Threading.Thread(new ThreadStart(m_prx.Start));
    				proxythread.Start();
    Inside the Start() method, I need to have some sort of listener, waiting for connections; on a first approach, I used a high level implementation that relies on httplistener class:

    Code:
    		 
    				 m_listener.Start();
    				System.Diagnostics.Debug.WriteLine("Listening socket on port " + m_port);
    				
    				while (true)
    				{
    					HttpListenerContext request = m_listener.GetContext();
    					ThreadPool.QueueUserWorkItem(ProcessRequest, request);
    This relies on the threadPool, which means .NET handles the multithreading at OS level;
    The function Process Request is, in the essence quite simple: it issues a webrequest (actually httpWebrequest) and appends all the stuff (credentials, headers, etc); then,

    Code:
     
    						HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
    						//create cache object
    						request.Credentials = AddCache(uri);
    						request.ClientCertificates.Add(SisService.GetClientCertificate());
    Then, it grabbs the stream:

    Code:
    						buffer = new byte[BUFFER_SIZE];
    						Stream instream = context.Request.InputStream;
    						int incount = instream.Read(buffer, 0, buffer.Length);
    						while (incount > 0)
    						{
    							request.GetRequestStream().Write(buffer, 0, incount);
    							incount = instream.Read(buffer, 0, buffer.Length);
    						}
    						// Wait for Response
    						WebResponse response = request.GetResponse();
    and it transfers it into the response:

    Code:
    						// Transfer the body data from the WebResponse
    						buffer = new byte[BUFFER_SIZE];
    						Stream outstream = response.GetResponseStream();
    						int outcount = outstream.Read(buffer, 0, buffer.Length);
    						while (outcount > 0)
    						{
    							context.Response.OutputStream.Write(buffer, 0, outcount);
    							outcount = outstream.Read(buffer, 0, buffer.Length);
    						}
    						// Close streams
    						instream.Close();
    						outstream.Close();
    						context.Response.OutputStream.Close();
    There is some missing code here, but this is pretty much the general idea.
    It works pretty well, and it is quite fast. However, sometimes (and I believe it is when there are sycnhronous or almost syncrhonous requests from clients) it ends up in this situation (exception):

    Code:
    A first chance exception of type 'System.Net.HttpListenerException' occurred in System.dll
    An operation was attempted on a nonexistent network connection
    I thought it could be a problem with the server, so I tested it with a different server but no luck: same error, when multiple requests were thrown almost at the same time.
    (I also thought the firewall might be intercepting something here, so I disabled it but it also did not have any influence).
    So I guess the problem would be with my code...

    My perspective was that the httplistener class was not really tackling the multithreading, which I need to have working properly because of the simultaneous requests from clients...

    After this, I tried different implementations:
    - an asynchronous GetContext (beginGetContext)
    - implementation with real sockets: TCPListener and finally raw sockets;

    The implementation with sockets is more or less like this:

    Code:
    				TcpListener listener = new TcpListener(IPAddress.Any, m_port);
    				listener.Start();
    
    				DoBeginAcceptSocket(listener);
    (I also use a ManualResetEvent here to send signals about the threads)
    Then the callback:

    Code:
    	public static void DoBeginAcceptSocket(TcpListener listener)
    	{
    		// Set the event to nonsignaled state.
    		tcpClientConnected.Reset();
    
    		// Start to listen for connections from a client.
    		//Console.WriteLine("Waiting for a connection...");
    
    		// Accept the connection. 
    		// BeginAcceptSocket() creates the accepted socket.
    		listener.BeginAcceptSocket(
    			new AsyncCallback(ProcessSocket), listener);
    		// Wait until a connection is made and processed before 
    		// continuing.
    		tcpClientConnected.WaitOne();
    	}

    And the callback "ProcessSocket", is a bit similar to "ProcessRequest", except that is a bit more complex; In the end, since we are not inside a while loop, I need to call DoBeginAcceptSocket again;

    This approach, also did not got me out of the problem... now I get a different error, which I think is related to the same issue (except is a different class of exception):

    Code:
    A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
    An existing connection was forcibly closed by the remote host.
    (I also tried a version with the sinchronous "AcceptSocket", with the same results);
    I am runnning a bit out of ideas here, about what may be the problem... has anyone incurred into this before? I would really appreciate any tips/suggestions on this that could put me into the right direction...
    I have to add that I am able to catch this error and carry on (even if I have to restart the listener) and in many cases is not a problem (apart from that the user does not see some output cause the requests didnt went trought...) however... not happy about this!
    Thanks in advance and have a good weekend!
    Jo

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Stream closed while writing

    Quote Originally Posted by doublebyte View Post
    This relies on the threadPool, which means .NET handles the multithreading at OS level;

    Code:
    ThreadPool.QueueUserWorkItem(ProcessRequest, request);
    Keep in mind that although QueueUserWorkItem manages the threads within the thread pool, it doesn't handle thread synchronization. What this means is that any resources you are sharing within the ProcessRequest class must be made thread safe. I don't know what the ProcessRequest method contains, but if it has access to its containing class fields or other data, you may have a synchronization issue (which causes data corruption).

  3. #3
    Join Date
    Jul 2009
    Location
    London
    Posts
    13

    Resolved Re: Stream closed while writing

    Hi Arjay, thanks for your answer!
    What I'm doing inside this request is actually thread safe (I think), since Im throwing requests to a (multitreaded) webserver and then displaying them in a client (the client is inside the httpListenerContext itself, through its response object);
    However, I decided that was better to go to explicit threading anyway (giving up on the ThreadPool and Asynchronous webrequests, that don't seem to work well with my problem).
    Apart from being much faster (cause I now take advantage of the parallelism), the application seems to throw that odd exception less often. Since I am able to catch it, and there is no real disturb for the client (it seems to render ok, despite some requests not being correctly responded) I decided to leave it as it is.
    I googled a lot for this exception, and I don't seem to fidn any solution for the problem; maybe it is expected that sometimes the stream fails?

    Code:
    A first chance exception of type 'System.Net.HttpListenerException' occurred in System.dll
    System.Net.HttpListenerException: An operation was attempted on a nonexistent network connection
       at System.Net.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 size)
    AFAIK, most people seem to be swallowing this exception. Anyway, I will close this problem here but if anybody has something new to add about this, it will be always good to know
    cheers,
    Jo

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured