Main Page | Class Hierarchy | Class List | File List | Class Members

ConnectionManager.cs

00001 using System;
00002 using System.Net;
00003 using System.Threading;
00004 using System.Net.Sockets;
00005 using System.Text;
00006 using System.IO;
00007 using System.Collections;
00008 using Common;
00009 
00010 namespace Client {
00014         public class ConnectionManager {
00015                 ClientControl clientControl; // parent client control object
00016 
00017                 public TcpListener listener; // listens for incoming connections
00018                 Thread processingThread; // thread to listen for connections
00019                 
00020                 //Logger myLogger; // logs client-processed requests
00021                 ArrayList connectionList; 
00022 
00027                 public ConnectionManager(ClientControl clientControl) {
00028                         this.clientControl = clientControl;
00029                         this.listener = new TcpListener(new IPEndPoint(IPAddress.Any, clientControl.settings.ProxyListenPort)); 
00030 //                      myLogger = new Logger(clientControl.settings);
00031                         connectionList = new ArrayList();
00032                 }
00033 
00037                 public void Start() {
00038                         processingThread = new Thread(new ThreadStart(Run));
00039                         listener = new TcpListener(clientControl.settings.ProxyListenIP, clientControl.settings.ProxyListenPort);
00040                         processingThread.Start();
00041                 }
00042 
00047                 void Run() {
00048                         TcpClient currentClient;
00049                         Connection currentConnection;
00050                         listener.Start();
00051                         try {
00052                                 while(true) { // main listening loop
00053                                         currentClient = listener.AcceptTcpClient();
00054                                         // create connection to handle it
00055                                         currentConnection = new Connection(currentClient, clientControl.userRequests,  connectionList); 
00056                                         // start the connection processing it
00057                                         ArrayList.Synchronized(connectionList).Add(currentConnection);
00058                                         currentConnection.Process();
00059                                 }
00060                         } catch (ThreadAbortException) {
00061                                 //Console.WriteLine("[Received Listener shutdown command]");
00062                         }
00063                         listener.Stop();
00064                 }
00065 
00069                 public void Stop() {
00070                         Console.WriteLine("+++ Stopping Connection Manager +++");
00071                         if (processingThread != null && processingThread.IsAlive) {
00072                                 processingThread.Abort();
00073                         }
00074                         // close all connections
00075                         try {
00076                                 while (ArrayList.Synchronized(connectionList).Count > 0) {
00077                                         Connection con = (Connection)connectionList[0];
00078                                         if (con != null) {
00079                                                 con.Close();
00080                                         } else {
00081                                                 ArrayList.Synchronized(connectionList).Remove(null);
00082                                         }
00083                                 }
00084                                 foreach (object o in connectionList) {
00085                                         if (o != null) {
00086                                                 ((Connection)o).Close();
00087                                         }
00088                                 }
00089                         } catch (Exception ex) {
00090                                 Console.Error.WriteLine("*** Error closing open connections ***\n{0}", ex);
00091                         }
00092                         if (processingThread != null) {
00093                                 processingThread.Join();}
00094                         Console.WriteLine("+++ Connection Manager Stopped +++");
00095                 }
00096         }
00097 
00098         /******************************************************************************************/
00099         public class Connection  {
00100                 TcpClient connection;
00101                 NetworkStream netStream;
00102                 bool haveRequest = false;
00103 
00104                 Thread processingThread;
00105                 ClientHTTPRequestQueueObject currentRequest;
00106                 HTTPObjectQueue requestOutputQueue;
00107 //              DateTime startTime;
00108 //              DateTime endTime;
00109                 ArrayList connections;
00110                         
00111                 public Connection(TcpClient newClient, HTTPObjectQueue requestOutputQueue, ArrayList connections) {
00112                         this.connections = connections;
00113                         processingThread = new Thread(new ThreadStart(this.Run));
00114                         this.connection = newClient;
00115                         this.requestOutputQueue = requestOutputQueue;
00116                         netStream = connection.GetStream();
00117                 }
00118 
00122                 public void Process() {
00123                         processingThread.Start();
00124                 }
00125 
00126         
00130                 void Run() {
00131 //                      startTime = DateTime.Now;
00132                         try {
00133                                 currentRequest = new ClientHTTPRequestQueueObject(netStream); // create HTTP Request from the socket
00134                                 // holds socket open for response later. 
00135                                 haveRequest = true;
00136                                 currentRequest.connection = this;
00137                                 requestOutputQueue.EnqueueBlocking(currentRequest);
00138                         } catch (Exception ex) {
00139                                 Console.Error.WriteLine("*** Unable to process connection from browser ***\n{0}", ex);
00140                                 Close(); // shut down the connection.
00141                         }
00142                 }
00143 
00148                 public HTTPRequest Request {
00149                         get {
00150                                 if (haveRequest) { return currentRequest; }
00151                                 else { throw new ApplicationException("Unable to fetch request on callback - no request stored"); }
00152                         }
00153                 }
00154 
00159                 public void SendResponse(HTTPResponse resp) {
00160                         try {
00161                                 byte[] outputBuffer = resp.ToHTTPByteArray();
00162                                 if (netStream != null && netStream.CanWrite) { // order of eval important, so is short-circuit eval. 
00163                                         netStream.Write(outputBuffer, 0, outputBuffer.Length);
00164                                         //Console.WriteLine("<<< Sent {0} to broswer", currentRequest.URI);
00165                                 } else {
00166                                         throw new ApplicationException("Bad or missing network stream to send response over");
00167                                 } 
00168 //                              if (myLogger != null) {
00169 //                                      endTime = DateTime.Now;
00170 //                                      //myLogger.Log(currentRequest.URI, startTime, endTime);
00171 //                              }
00172                         } catch (Exception ex) {
00173                                 Console.Error.WriteLine("*** Unable to write HTTP Response to client, terminating browser connection ***\n{0}", ex);
00174                         } finally {
00175                                 Close();
00176                         }
00177                 }
00178 
00182                 public void Close() {
00183                         if (netStream != null) { netStream.Close(); }
00184                         if (connection != null) { connection.Close(); }
00185                         ArrayList.Synchronized(connections).Remove(this);
00186                 }
00187                 
00188         }
00189         
00190 }

Generated on Mon May 8 22:07:27 2006 by  doxygen 1.3.9.1