/// <summary> /// Looks up the connection manager responsible for the address book item and disconnects it from the remote host /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnDisconnectSessionForAddressBookItem(object sender, BackgroundThreadStartEventArgs e) { // retrieve the address book item that is requiring attention AddressBookItem item = (AddressBookItem)e.Args[0]; try { lock (_sessionManagers) { AddressBookItemConnectionManager manager = _sessionManagers[item]; if (manager != null) { manager.Disconnect(); } } } catch (ThreadAbortException) { // ignore thread abort exceptions } catch (Exception ex) { Debug.WriteLine(ex); } }
/// <summary> /// Runs the background thread that listens for incoming connections /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnThreadRun(object sender, BackgroundThreadStartEventArgs e) { try { IPEndPoint ep = (IPEndPoint)e.Args[0]; Debug.Assert(ep != null); Trace.WriteLineIf(_verbose, string.Format("Binding to the end point '{0}'.", ep.ToString()), MY_TRACE_CATEGORY); _listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _listeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); _listeningSocket.Bind(ep); Trace.WriteLineIf(_verbose, string.Format("Listening for inbound connections on '{0}'.", ep.ToString()), MY_TRACE_CATEGORY); while (true) { _listeningSocket.Listen(100); // pending connections queue length // accept the connection Socket socket = _listeningSocket.Accept(); Trace.WriteLineIf(_verbose, string.Format("Accepted an inbound connection from '{0}'.", socket.RemoteEndPoint.ToString()), MY_TRACE_CATEGORY); // create a new connection for the connection HttpConnection connection = new HttpConnection(socket, _verbose); connection.RequestDispatcher = _dispatcher; connection.Exception += new ExceptionEventHandler(this.OnConnectionException); connection.Opened += new HttpConnectionEventHandler(this.OnConnectionOpened); connection.Closed += new HttpConnectionEventHandler(this.OnConnectionClosed); connection.IsServerSideConnection = true; connection.BeginSession(true); } } catch (ThreadAbortException) { } catch (Exception ex) { this.OnException(this, new ExceptionEventArgs(ex)); } }
/// <summary> /// The background thread procedure that will handle scrolling the Image /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void HandleThreadRun(object sender, BackgroundThreadStartEventArgs e) { try { while (true) { if (this.DesignMode) { Thread.Sleep(500); } else { // step forward on the offset _offset += _step; // reset the offset if we hit the edge if (_offset >= this.Width) _offset = 0; // repaint this.Invalidate(); // snooze a bit Thread.Sleep(_frameRate); } } } catch(System.Threading.ThreadAbortException) { // watch out for this little guy. :P // some days i still feel like this is not right that an exception is thrown // but i suppose there's not really any better way for the framework to stop the thread // and give you control back } catch(Exception ex) { Log.WriteLine(ex); } }
/// <summary> /// Tries to receive data from the network on a background thread /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void OnReadFromSocket(object sender, BackgroundThreadStartEventArgs threadStartArgs) { try { // create a new message reader _messageReader = new HttpMessageReader(); while (true) { try { // read a single message HttpMessage message = null; // lock the reader lock (_messageReader) { // read a message message = _messageReader.Read(_socket, _stopEvent); } // what type of message is this ? switch (message.Type) { /* * process the request * */ case HttpMessageTypes.HttpRequest: { // process the request by dispatching it and then responding if need be this.OnRequestReceived(this, new HttpRequestCancelEventArgs(new HttpRequest(message), false)); break; } /* * process the response * */ case HttpMessageTypes.HttpResponse: { this.OnResponseReceived(this, new HttpResponseEventArgs(new HttpResponse(message))); break; } /* * an unknown message type * */ default: { // hopefully this will never happen! Debug.WriteLine(string.Format("A message of unknown type was received from '{0}'...\n{1}", message)); break; } } ; } catch (HttpMessageReaderAbortedException) { // the reader was aborted } catch (HttpConnectionClosedByPeerException) { /* * the remote host has closed the connection * */ this.Close(); return; } // see if we should stop receiving if (_stopEvent != null) { if (_stopEvent.WaitOne(1, false)) { /* * we have recieved a signal that we should stop receiving * and disconnect the current connection * */ if (_disconnectOnStop) { this.Close(); } return; } } } } catch (ThreadAbortException) { /* * the thread is aborting * */ if (_disconnectOnStop) { this.Close(); } } catch (ObjectDisposedException) { /* * the connection has closed the socket * */ this.Close(); } catch (SocketException ex) { // if the connection is reset, or a blocking call was cancelled with a call to cancelblockingcall if (ex.ErrorCode == (int)SocketErrors.WSAECONNRESET || ex.ErrorCode == (int)SocketErrors.WSAEINTR) { this.Close(); return; } // notify that this connection has encountered an exception this.OnException(this, new ExceptionEventArgs(ex)); } catch (Exception ex) { // notify that this connection has encountered an exception this.OnException(this, new ExceptionEventArgs(ex)); } }
/// <summary> /// Tries to receive data from the network on a background thread /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void OnReadFromSocket(object sender, BackgroundThreadStartEventArgs threadStartArgs) { try { // create a new message reader _messageReader = new HttpMessageReader(); while (true) { try { // if (!_isServerSideConnection) // Debug.WriteLine(string.Format("User-Agent connection '{0}' trying to read next incoming message from '{1}'", _id.ToString(), this.RemoteAddress.ToString()), MY_TRACE_CATEGORY); // else // Debug.WriteLine(string.Format("Server-Side connection '{0}' trying to read next incoming message from '{1}'", _id.ToString(), this.RemoteAddress.ToString()), MY_TRACE_CATEGORY); // read a single message HttpMessage message = null; // lock the reader lock (_messageReader) { // read a message message = _messageReader.Read(_socket, _stopEvent); } // what type of message is this ? switch (message.Type) { /* * process the request * */ case HttpMessageTypes.HttpRequest: { // create a request event args HttpRequestCancelEventArgs e = new HttpRequestCancelEventArgs(new HttpRequest(message), false); // process the request by dispatching it and then responding if need be this.OnRequestReceived(this, e); // // next check the request to see if the connection should be closed after the response was sent // if (HttpUtils.Contains(e.Request.Connection, HttpConnections.Close)) // { // // yup, they wanted us to close the connection automatically so lets do that now // this.Close(); // return; // } break; } /* * process the response * */ case HttpMessageTypes.HttpResponse: { this.OnResponseReceived(this, new HttpResponseEventArgs(new HttpResponse(message))); break; } /* * an unknown message type * */ default: { // hopefully this will never happen! Debug.WriteLine(string.Format("A message of unknown type was received from '{0}'...\n{1}", message)); break; } } ; } catch (HttpMessageReaderAbortedException) { // the reader was aborted } catch (HttpConnectionClosedByPeerException) { /* * the remote host has closed the connection * */ this.Close(); return; } // see if we should stop receiving if (_stopEvent != null) { if (_stopEvent.WaitOne(1, false)) { /* * we have recieved a signal that we should stop receiving * and disconnect the current connection * */ if (_disconnectOnStop) { this.Close(); } return; } } } } catch (ThreadAbortException) { /* * the thread is aborting * */ if (_disconnectOnStop) { this.Close(); } } catch (ObjectDisposedException) { /* * the connection has closed the socket * */ this.Close(); } catch (SocketException ex) { // if the connection is reset, or a blocking call was cancelled with a call to cancelblockingcall if (ex.ErrorCode == (int)SocketErrors.WSAECONNRESET || ex.ErrorCode == (int)SocketErrors.WSAEINTR) { this.Close(); return; } // notify that this connection has encountered an exception this.OnException(this, new ExceptionEventArgs(ex)); } catch (Exception ex) { // notify that this connection has encountered an exception this.OnException(this, new ExceptionEventArgs(ex)); } // finally // { // Debug.WriteLineIf(!_isServerSideConnection, string.Format("*** exiting receiving thread loop for connection '{0}'", _id.ToString()), MY_TRACE_CATEGORY); // } }
/// <summary> /// Creates a connection manager for the address book item, and connects the connection to the remote host specified by the address book item /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnConnectSessionForAddressBookItem(object sender, BackgroundThreadStartEventArgs e) { // retrieve the address book item that is requiring attention AddressBookItem item = (AddressBookItem)e.Args[0]; bool disconnectFirst = (bool)e.Args[1]; bool verboseSession = (bool)e.Args[2]; bool autoRecv = (bool)e.Args[3]; try { /* * if we are supposed to disconnect the current connection first * */ if (disconnectFirst) { lock (_sessionManagers) { // look up the item to see if an existing connection is already in use AddressBookItemConnectionManager prevManager = _sessionManagers[item]; // if a connection manager is found for the item then disconnect it if (prevManager != null) { prevManager.Disconnect(); } } } // create a new tcp connection in verbose mode HttpConnection connection = new HttpConnection(verboseSession); // create a new connection manager to manage the connection AddressBookItemConnectionManager manager = new AddressBookItemConnectionManager(item, connection); // wire up to the manager's events manager.ConnectionEstablishContext += new AddressBookItemConnectionManagerContextEventHandler(OnConnectionEstablishContext); manager.ConnectionResolvingAddress += new AddressBookItemConnectionManagerResolvingAddressEventHandler(OnConnectionResolvingAddress); manager.BeforeConnectionOpened += new AddressBookItemConnectionManagerCancelEventHandler(OnBeforeConnectionOpened); manager.BeforeConnectionClosed += new AddressBookItemConnectionManagerCancelEventHandler(OnBeforeConnectionClosed); manager.ConnectionOpened += new AddressBookItemConnectionManagerEventHandler(OnConnectionOpened); manager.ConnectionClosed += new AddressBookItemConnectionManagerEventHandler(OnConnectionClosed); manager.ConnectionException += new AddressBookItemConnectionManagerExceptionEventHandler(OnConnectionException); // create the thread context that will enable us to determine the background thread upon which this connection manager is operating manager.ThreadContext = new AddressBookItemBackgroundThreadContext((BackgroundThread)sender, item); // instruct the manager to connect the connection to the remote host // pass it instructions on whether it should begin receiving automatically or not // NOTE: In almost every case from a client created connection this will be false. // Only server created sessions will be set to automatically receive. manager.Connect(autoRecv, manager.ThreadContext); // add the connection manager to our list of connection managers lock (_sessionManagers) _sessionManagers.Add(manager); } catch (ThreadAbortException) { // ignore thread abort exceptions } catch (Exception ex) { Debug.WriteLine(ex); } }
private void OnThreadRun(object sender, BackgroundThreadStartEventArgs e) { // const int SOCKET_ERROR = -1; try { string address = (string)e.Args[0]; int timesToPing = (int)e.Args[1]; #region Address Resolution bool isHostName = false; IPAddress ipAddress = null; try { ipAddress = IPAddress.Parse(address); } catch (Exception) { try { ipAddress = Dns.GetHostByName(address).AddressList[0]; isHostName = true; } catch (Exception ex) { throw ex; } } #endregion // create the source and destination end points IPEndPoint sourceIPEP = new IPEndPoint(IPAddress.Any, 0); IPEndPoint destinationIPEP = new IPEndPoint(ipAddress, 0); EndPoint source = sourceIPEP; EndPoint destination = destinationIPEP; // create an icmp socket Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); // create an icmp echo packet IcmpEchoPacket packet = new IcmpEchoPacket(); // serialize the packet to a byte array byte[] bytes = IcmpPacket.GetBytes(packet); // create the checksum for the packet based on it's data packet.Checksum = IcmpPacket.CreateChecksum(bytes); // create a packet reader and writer IcmpPacketReader reader = new IcmpPacketReader(); IcmpPacketWriter writer = new IcmpPacketWriter(); // raise the ping started event this.OnPingStarted(this, new PingerEventArgs(address, isHostName, ipAddress, timesToPing)); // ping statistics int packetsSent = 0; int packetsReceived = 0; int[] elapsedTimes = new int[timesToPing]; // now ping the destination X number of times as instructed for (int i = 0; i < timesToPing; i++) { int start = System.Environment.TickCount; int end = 0; int elapsed = 0; try { // send the icmp echo request int bytesSent = writer.Write(socket, packet, destination); packetsSent++; // wait for a response IcmpPacket response; int bytesReceived; bool receivedResponse = reader.Read(socket, source, 1000 /* 1 second timeout */, out response, out bytesReceived); // calculate the end and elapsed time in milliseconds end = System.Environment.TickCount; elapsed = end - start; elapsedTimes[i] = elapsed; if (receivedResponse) { packetsReceived++; } // raise the ping result event this.OnPingResult(this, new PingerResultEventArgs(address, isHostName, ipAddress, timesToPing, !receivedResponse, bytesReceived, elapsed)); } catch (Exception ex) { /* * this should never hit * * raw sockets shouldn't pose a problem when targeting icmp * */ this.OnException(this, new ExceptionEventArgs(ex)); } } // calculate the percentage lost int percentLost = (int)(((double)(packetsSent - packetsReceived) / (double)packetsSent) * 100d); int min = int.MaxValue; int max = int.MinValue; int average = 0; int total = 0; for (int i = 0; i < timesToPing; i++) { if (elapsedTimes[i] < min) { min = elapsedTimes[i]; } if (elapsedTimes[i] > max) { max = elapsedTimes[i]; } total += elapsedTimes[i]; } average = (int)((double)total / (double)timesToPing); PingerStatisticsEventArgs ea = new PingerStatisticsEventArgs( address, isHostName, ipAddress, timesToPing, packetsSent, packetsReceived, packetsSent - packetsReceived, percentLost, min, max, average); this.OnPingStatistics(this, ea); } catch (ThreadAbortException) { } catch (Exception ex) { Debug.WriteLine(ex); this.OnException(this, new ExceptionEventArgs(ex)); } finally { } }
/// <summary> /// The background thread's entry method /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void HandleThreadRun(object sender, BackgroundThreadStartEventArgs e) { try { // first try the Type var, if we can create one using Reflection we don't need the provider if (_type != null) { // make sure that the type specified inherits from Form or is directly a Form class TypeUtilities.AssertTypeIsSubclassOfBaseType(_type, typeof(Form)); // create a new instance of the window using the Type specified _window = TypeUtilities.CreateInstanceOfType(_type, Type.EmptyTypes, new object[] {}) as Form; } else { // use the provider to create an instance of the window _window = _provider.CreateWindow(e.Args); } // make sure we have a window instance if (_window == null) { throw new ArgumentNullException("InnerWindow", "No window instance was created."); } // raise an event so that we can modify the window as needed before it is shown this.OnWindowCreated(this, new AsyncWindowManagerEventArgs(this)); // release the start method by signalling we have created the window _createdEvent.Set(); // see if an owner was specified IWin32Window owner = null; if (e.Args != null) { if (e.Args.Length > 0) { owner = (IWin32Window)e.Args[0]; } } // show the window modally on this thread if (owner != null) { _window.Owner = owner as Form; _window.ShowDialog(owner); } else { _window.ShowDialog(); } } catch (Exception ex) { _failed = true; Log.WriteLine(ex); this.OnException(this, new AsyncWindowManagerExceptionEventArgs(this, ex)); } finally { _window = null; _createdEvent.Set(); } }