using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace MailServer.SMTPServer { public delegate void ReceivedLineEventHandler(string line); class SmtpSession { public event ReceivedLineEventHandler NewLine; private TcpClient Client { get; set; } public IPEndPoint IPEndPoint { get; private set; } private NetworkStream Stream { get; set; } private Encoding Encoding = Encoding.ASCII; private string Others; private Thread Worker; private bool Active = true; private int SessionID { get; set; } public SmtpSession(TcpClient client) { Client = client; IPEndPoint = (IPEndPoint)client.Client.RemoteEndPoint; Stream = client.GetStream(); Others = ""; SessionID = new Random(123).Next(10000, 99999); Logging.AddLogMessage(Logging.LoggingType.INFO, "New SMTPSession with id '" + SessionID + "' started"); Worker = new Thread(ReadClientInput); Worker.Start(); } public void SendExtensionResponse(Extensions extension) => SendResponse("250-" + extension.ToString()); public void SendResponse(ResponseCodes responseCode) => SendResponse(responseCode, ""); public void SendResponse(ResponseCodes responseCode, string args) => SendResponse(((int)responseCode).ToString() + " " + args); public void SendResponse(string response) { Logging.AddLogMessage(Logging.LoggingType.INFO, response); response += '\r' + '\n'; var bytes = Encoding.UTF8.GetBytes(response); Stream.Write(bytes, 0, bytes.Length); } private void ReadClientInput() { while (Active) { if (Stream.DataAvailable) { byte[] buffer = new byte[Client.ReceiveBufferSize]; var readed = Stream.Read(buffer, 0, buffer.Length); var str = Encoding.GetString(buffer, 0, readed); lock (Others) { Others += str; } CheckLines(); } else { Thread.Sleep(10); } } } private bool r = false; private void CheckLines() { lock (Others) { var line = ""; foreach (char c in Others) { if (c.Equals('\r')) { r = true; } else if (r && c.Equals('\n')) { //Console.WriteLine(line); Logging.AddLogMessage(Logging.LoggingType.DEBUG, "Seession " + SessionID + ": received line: " + line); NewLine(line); line = ""; } else { line += c; r = false; } } Others = line; } } public void CloseAll() { Stream.Dispose(); Client.Dispose(); Active = false; } } }