POP3_Server.cs
上传用户:horngjaan
上传日期:2009-12-12
资源大小:2882k
文件大小:12k
- using System;
- using System.IO;
- using System.ComponentModel;
- using System.Collections;
- using System.Diagnostics;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- using System.Windows.Forms;
- using LumiSoft.MailServer;
- namespace LumiSoft.MailServer.POP3
- {
- #region Event delegates
- /// <summary>
- /// Represents the method that will handle the GetMessgesList event for POP3_Server.
- /// </summary>
- /// <param name="sender">The source of the event. </param>
- /// <param name="e">A GetMessagesInfo_EventArgs that contains the event data.</param>
- public delegate void GetMessagesInfoHandler(object sender,GetMessagesInfo_EventArgs e);
- /// <summary>
- /// Represents the method that will handle the GetMailEvent event for POP3_Server.
- /// </summary>
- /// <param name="sender">The source of the event. </param>
- /// <param name="e">A GetMessage_EventArgs that contains the event data.</param>
- public delegate void GetMessageHandler(object sender,GetMessage_EventArgs e);
- /// <summary>
- /// Represents the method that will handle the DeleteMessageEvent event for POP3_Server.
- /// </summary>
- /// <param name="sender">The source of the event. </param>
- /// <param name="e">A DeleteMessage_EventArgs that contains the event data.</param>
- public delegate void DeleteMessageHandler(object sender,DeleteMessage_EventArgs e);
- /// <summary>
- /// Represents the method that will handle the GetTopLines event for POP3_Server.
- /// </summary>
- /// <param name="sender">The source of the event. </param>
- /// <param name="e">A GetTopLines_Eventargs that contains the event data.</param>
- public delegate void GetTopLinesHandler(object sender,GetTopLines_Eventargs e);
- #endregion
- /// <summary>
- /// POP3 server component.
- /// </summary>
- public class POP3_Server : System.ComponentModel.Component
- {
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.Container components = null;
- private TcpListener POP3_Listener = null;
- private Hashtable m_SessionTable = null;
-
- private string m_IPAddress = "ALL"; // Holds IP Address, which to listen incoming calls.
- private int m_port = 110; // Holds port number, which to listen incoming calls.
- private int m_MaxThreads = 10; // Holds maximum allowed Worker Threads (Users).
- private bool m_enabled = false; // If true listens incoming calls.
- private bool m_LogCmds = false; // If true, writes POP3 commands to log file.
- private int m_SessionIdleTimeOut = 80000; // Holds session idle timeout.
- private int m_CommandIdleTimeOut = 60000; // Holds command ilde timeout.
- private int m_MaxBadCommands = 8; // Holds maximum bad commands allowed to session.
-
- #region Event declarations
- /// <summary>
- /// Occurs when new computer connected to POP3 server.
- /// </summary>
- public event ValidateIPHandler ValidateIPAddress = null;
- /// <summary>
- /// Occurs when connected user tryes to authenticate.
- /// </summary>
- public event AuthUserEventHandler AuthUser = null;
- /// <summary>
- /// Occurs when server needs to know logged in user's maibox messages.
- /// </summary>
- public event GetMessagesInfoHandler GetMessgesList = null;
- /// <summary>
- /// Occurs when user requests specified message.
- /// </summary>
- public event GetMessageHandler GetMailEvent = null;
- /// <summary>
- /// Occurs when user requests delete message.
- /// </summary>
- public event DeleteMessageHandler DeleteMessageEvent = null;
- /// <summary>
- /// Occurs when user requests specified message TOP lines.
- /// </summary>
- public event GetTopLinesHandler GetTopLines = null;
- /// <summary>
- /// Occurs when server has system error(Unknown error).
- /// </summary>
- public event ErrorEventHandler SysError = null;
- /// <summary>
- /// Occurs when POP3 session has finished and session log is available.
- /// </summary>
- public event LogEventHandler SessionLog = null;
- #endregion
- #region Constructors
- /// <summary>
- ///
- /// </summary>
- /// <param name="container"></param>
- public POP3_Server(System.ComponentModel.IContainer container)
- {
- // Required for Windows.Forms Class Composition Designer support
- container.Add(this);
- InitializeComponent();
- //
- // TODO: Add any constructor code after InitializeComponent call
- //
- }
- /// <summary>
- ///
- /// </summary>
- public POP3_Server()
- {
- // Required for Windows.Forms Class Composition Designer support
- InitializeComponent();
- //
- // TODO: Add any constructor code after InitializeComponent call
- //
- }
- #endregion
- #region function Dispose
- /// <summary>
- /// Clean up any resources being used and STOPs POP3 server.
- /// </summary>
- public new void Dispose()
- {
- base.Dispose();
- Stop();
- }
- #endregion
-
- #region Component Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- components = new System.ComponentModel.Container();
- }
- #endregion
- #region function Start
- /// <summary>
- /// Starts POP3 Server.
- /// </summary>
- private void Start()
- {
- try
- {
- if(!m_enabled && !this.DesignMode){
- m_SessionTable = new Hashtable();
- Thread startPOP3Server = new Thread(new ThreadStart(Run));
- startPOP3Server.Start();
- }
- }
- catch(Exception x)
- {
- OnSysError(x,new System.Diagnostics.StackTrace());
- }
- }
- #endregion
- #region function Stop
- /// <summary>
- /// Stops POP3 Server.
- /// </summary>
- private void Stop()
- {
- try
- {
- if(POP3_Listener != null){
- POP3_Listener.Stop();
- }
- }
- catch(Exception x)
- {
- OnSysError(x,new System.Diagnostics.StackTrace());
- }
- }
- #endregion
- #region function Run
- /// <summary>
- /// Starts server message loop.
- /// </summary>
- private void Run()
- {
- try
- {
- // check which ip's to listen (all or assigned)
- if(m_IPAddress == "(All Unassigned)"){
- POP3_Listener = new TcpListener(m_port);
- }
- else{
- POP3_Listener = new TcpListener(IPAddress.Parse(m_IPAddress),m_port);
- }
- // Start listening
- POP3_Listener.Start();
- while(true)
- {
- // Check if maximum allowed thread count isn't exceeded
- if(m_SessionTable.Count < m_MaxThreads){
- // Thread is sleeping, until a client connects
- Socket clientSocket = POP3_Listener.AcceptSocket();
- string sessionID = clientSocket.GetHashCode().ToString();
- //****
- _LogWriter logWriter = new _LogWriter(this.SessionLog);
- POP3_Session session = new POP3_Session(clientSocket,this,sessionID,logWriter);
- session.DeleteMessageEvent = this.DeleteMessageEvent;
- session.GetMailEvent = this.GetMailEvent;
- session.GetMessgesList = this.GetMessgesList;
- session.GetTopLines = this.GetTopLines;
- session.ValidateIPAddress = this.ValidateIPAddress;
- session.AuthUser = this.AuthUser;
- ThreadStart tStart = new ThreadStart(session.StartProcessing);
- Thread clientThread = new Thread(tStart);
- // Add session to session list
- AddSession(sessionID,session,logWriter);
- // Start proccessing
- clientThread.Start();
- }
- else{
- Thread.Sleep(300);
- }
- }
- }
- catch(ThreadInterruptedException e)
- {
- Thread.CurrentThread.Abort();
- }
- catch(Exception x)
- {
- if(x.Message != "A blocking operation was interrupted by a call to WSACancelBlockingCall"){
- OnSysError(x,new System.Diagnostics.StackTrace());
- }
- }
- }
- #endregion
- #region Session handling stuff
- #region function AddSession
- /// <summary>
- /// Adds session.
- /// </summary>
- /// <param name="sessionID">Session ID.</param>
- /// <param name="session">Session object.</param>
- /// <param name="logWriter">Log writer.</param>
- internal void AddSession(string sessionID,POP3_Session session,_LogWriter logWriter)
- {
- m_SessionTable.Add(sessionID,session);
- if(m_LogCmds){
- logWriter.AddEntry("//----- Sys: 'Session:'" + sessionID + " added" + DateTime.Now);
- }
- }
- #endregion
- #region function RemoveSession
- /// <summary>
- /// Removes session.
- /// </summary>
- /// <param name="sessionID">Session ID.</param>
- /// <param name="logWriter">Log writer.</param>
- internal void RemoveSession(string sessionID,_LogWriter logWriter)
- {
- lock(this){
- if(!m_SessionTable.Contains(sessionID)){
- OnSysError(new Exception("Session '" + sessionID + "' doesn't exist."),new System.Diagnostics.StackTrace());
- return;
- }
- m_SessionTable.Remove(sessionID);
- }
- if(m_LogCmds){
- logWriter.AddEntry("//----- Sys: 'Session:'" + sessionID + " removed" + DateTime.Now);
- }
- }
- #endregion
- #region function IsUserLoggedIn
- /// <summary>
- /// Checks if user is logged in.
- /// </summary>
- /// <param name="userName">User name.</param>
- /// <returns></returns>
- internal bool IsUserLoggedIn(string userName)
- {
- lock(this){
- foreach(POP3_Session sess in m_SessionTable.Values){
- if(sess.UserName == userName){
- return true;
- }
- }
- }
-
- return false;
- }
- #endregion
- #endregion
- #region Properties implementation
- /// <summary>
- /// Gets or sets whick IP address to listen.
- /// </summary>
- [
- Description("IP Address to Listen POP3 requests"),
- DefaultValue("ALL"),
- ]
- public string IpAddress
- {
- get{ return m_IPAddress; }
- set{ m_IPAddress = value; }
- }
- /// <summary>
- /// Gets or sets which port to listen.
- /// </summary>
- [
- Description("Port to use for POP3"),
- DefaultValue(110),
- ]
- public int Port
- {
- get{ return m_port; }
- set{ m_port = value; }
- }
- /// <summary>
- /// Gets or sets maximum session threads.
- /// </summary>
- [
- Description("Maximum Allowed threads"),
- DefaultValue(10),
- ]
- public int Threads
- {
- get{ return m_MaxThreads; }
- set{ m_MaxThreads = value; }
- }
- /// <summary>
- /// Runs or stops server.
- /// </summary>
- [
- Description("Use this property to run and stop POP3 Server"),
- DefaultValue(false),
- ]
- public bool Enabled
- {
- get{ return m_enabled; }
- set{
- if(value){
- Start();
- }
- else{
- Stop();
- }
- m_enabled = value;
- }
- }
-
- /// <summary>
- /// Gets or sets if to log commands.
- /// </summary>
- public bool LogCommands
- {
- get{ return m_LogCmds; }
- set{ m_LogCmds = value; }
- }
- /// <summary>
- /// Session idle timeout.
- /// </summary>
- public int SessionIdleTimeOut
- {
- get{ return m_SessionIdleTimeOut; }
- set{ m_SessionIdleTimeOut = value; }
- }
- /// <summary>
- /// Command idle timeout.
- /// </summary>
- public int CommandIdleTimeOut
- {
- get{ return m_CommandIdleTimeOut; }
- set{ m_CommandIdleTimeOut = value; }
- }
- /// <summary>
- /// Gets or sets maximum bad commands allowed to session.
- /// </summary>
- public int MaxBadCommands
- {
- get{ return m_MaxBadCommands; }
- set{ m_MaxBadCommands = value; }
- }
-
- #endregion
- #region Events Implementation
- /// <summary>
- /// Raises SysError event.
- /// </summary>
- /// <param name="x"></param>
- /// <param name="stackTrace"></param>
- internal void OnSysError(Exception x,StackTrace stackTrace)
- {
- if(this.SysError != null){
- this.SysError(this,new Error_EventArgs(x,stackTrace));
- }
- }
- #endregion
- }
- }