| CodeGuru Home | VC++ / MFC / C++ | .NET / C# | Visual Basic | Newsletters | VB Forums | Developer.com |
|
|
|||||||
| C-Sharp Programming Post questions, answers, and comments about C#. |
![]() |
|
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
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(); 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);
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()); 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();
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();
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 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); 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 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 |
![]() |
| Bookmarks |
| Tags |
| exception , multithreading socket , proxy |
|
||||||
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|