this is the code of my StreamServer class:
Expand|Select|Wrap|Line Numbers
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- using System.Threading;
- namespace Tools.IO
- {
- #region HelperClass ClientEventArgs
- /// <summary>
- /// Helper class that holds information about the client
- /// that connects to the server.
- /// </summary>
- public class ClientEventArgs : EventArgs
- {
- #region Constructor
- /// <summary>
- /// Creates a new instance of the ClientEventArgs class.
- /// </summary>
- /// <param name="client">The TCPClient that has connected/disconnected from the server.</param>
- public ClientEventArgs(TcpClient client)
- {
- // save the client.
- Client = client;
- }
- #endregion
- #region Public Properties
- /// <summary>
- /// Gets or sets the TcpClient that has connected/disconnected from the server.
- /// </summary>
- public TcpClient Client
- {
- get { return m_client; }
- set { m_client = value; }
- }
- #endregion
- #region Private Fields
- private TcpClient m_client; // The TcpClient that has connected/disconnected from the server.
- #endregion
- }
- #endregion
- public sealed class StreamServer
- {
- #region Events
- /// <summary>
- /// This event gets fired when a client connects to the StreamServer.
- /// </summary>
- public event EventHandler<ClientEventArgs> OnClientConnected
- {
- add { lock (m_eventlock) { OnClientConnected += value; } }
- remove { lock (m_eventlock) { OnClientConnected -= value; } }
- }
- /// <summary>
- /// This event gets fired when a client disconnects from the StreamServer.
- /// </summary>
- public event EventHandler<ClientEventArgs> OnClientDisconnected
- {
- add { lock (m_eventlock) { OnClientDisconnected += value; } }
- remove { lock (m_eventlock) { OnClientDisconnected -= value; } }
- }
- #endregion
- #region Private Methods
- private void ListenRoutine()
- {
- // Try to enter the Monitor lock guarding the TcpListener.
- // If acquiring the lock fails, then fall through the function
- // and try again on the next call.
- if (Monitor.TryEnter(m_listenlock, 10))
- {
- // We succeeded in acquiring the lock on the TcpListener.
- // Check if a connection is pending, and if the TcpListener
- // is still initialized.
- // If there is no connection pending, fall through the function
- // and recheck on the next call.
- if ((m_listener != null) && (m_listener.Pending()))
- {
- // There is a connetion pending, accept this connection first.
- TcpClient client = m_listener.AcceptTcpClient();
- // Raise the OnClientConnectedEvent if possible.
- RaiseOnClientConnectedEvent(ref client);
- }
- }
- }
- private void RaiseOnClientConnectedEvent(ref TcpClient client)
- {
- // Take a copy of the event handler for the onConnected event.
- // That way we can raise the event safely without having to
- // worry about racing conditions between the call & unsbscribing
- // of the event.
- EventHandler<ClientEventArgs> handler = OnClientConnected;
- // Check if the handler is not null, fire the event if possible.
- if (handler != null)
- handler(this, new ClientEventArgs(client));
- }
- #endregion
- #region Private Fields
- private TcpListener m_listener;
- private readonly object m_listenlock;
- private Timer m_listentimer;
- private readonly object m_eventlock;
- private List<Fiber> m_fibers;
- private readonly object m_fiberlock;
- #endregion
- }
- }
What am I missing...?