您可能会看到我使用C#编写的一个小型SMTP服务器。 我包括整个代码(不包括一个类),但我希望你能很好地了解细节。 我对客户的DATA帖子感到厌烦,问题在于我的观点是“自动冲洗”不起作用。 客户端发送到我的服务器“DATA”,告诉我准备接收我的电子邮件的数据。 我需要回答“354启动邮件输入”,我这样做,我的问题是: 发送“354开始邮件输入”后,我需要在此功能中接收来自客户端的消息。
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace FakeSMTP
{
public class SMTPServer //: IDisposable
{
TcpClient client;
NetworkStream stream;
System.IO.StreamReader reader;
System.IO.StreamWriter writer;
//public void Dispose()
//{
// writer.Dispose();
// reader.Dispose();
// stream.Dispose();
//}
public SMTPServer(TcpClient client)
{
this.client = client;
stream = client.GetStream();
reader = new System.IO.StreamReader(stream);
writer = new System.IO.StreamWriter(stream);
writer.NewLine = "\r\n";
writer.AutoFlush = true;
}
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Loopback, 25);
listener.Start();
//using (SMTPServer handler = new SMTPServer(listener.AcceptTcpClient()))
while (true)
{
SMTPServer handler = new SMTPServer(listener.AcceptTcpClient());
Thread thread = new System.Threading.Thread(new ThreadStart(handler.Run));
thread.Start();
}
}
public void Run()
{
string sadress;
string radress;
string rserver;
bool auth = false;
writer.WriteLine("220 smtp.localsmtp.de ESMTP server ready");
for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
{
Console.Error.WriteLine("Read line {0}", line);
if (line.StartsWith("EHLO"))
{
writer.WriteLine("250-smtp.localsmtp.de");
//Auth ankuendigen
writer.WriteLine("250 AUTH PLAIN");
}
if (line.StartsWith("QUIT"))
{
writer.WriteLine("221 Bye Sweetie see ya");
client.Close();
}
#region auth
if (line.StartsWith("AUTH PLAIN"))
{
Console.WriteLine("client sendet Auth: " + line);
string [] pw = line.Split(new string[] { "PLAIN " }, StringSplitOptions.None);
byte[] bytes = Convert.FromBase64String(pw[1]);
string result = Encoding.BigEndianUnicode.GetString(bytes);
if (result == "12")
{
writer.WriteLine("235 2.7.0 Authentication successful");
auth = true;
}
else
{
Console.WriteLine("Falsche AUTH Daten");
writer.WriteLine("535 – Incorrect authentication data");
}
}
#endregion
#region sender
if (line.StartsWith("MAIL FROM") && auth == true)
{
string[] sadressa = line.Split(new string[] { "FROM:" }, StringSplitOptions.None);
sadress = sadressa[1];
//Absender
sadress = sadress.Replace("<","").Replace(">","");
//Debug
Console.WriteLine("Absender: " + sadress);
writer.WriteLine("250 OK");
}
#endregion
#region receiver
if (line.StartsWith("RCPT TO:") && auth == true)
{
string[] radressa = line.Split(new string[] { "RCPT TO:" }, StringSplitOptions.None);
radress = radressa[1];
//Empfänger
radress = radress.Replace("<", "").Replace(">", "");
if (samplesmtp.getMX.GetMXRecord(radress) != "invalid")
{
rserver = samplesmtp.getMX.GetMXRecord(radress);
Console.WriteLine("MX Record: " + rserver);
}
else
Console.WriteLine("ALARM");
//Debug
Console.WriteLine("Empfänger: " + radress);
writer.WriteLine("250 OK");
}
#endregion
#region data
if (line.StartsWith("DATA") && auth == true)
{
writer.WriteLine("354 start mail input");
var emailLine = reader.ReadLine();
while (!emailLine.Equals("."))
{
// add emailLine to the email body
string[] emailbody = new string[] {emailLine};
Console.WriteLine("Emailbody: " + emailbody[0]);
}
reader.Close();
writer.Close();
stream.Dispose();
writer.WriteLine("250 OK");
}
#endregion
}
}
}
}
尝试在代码中手动调用.Flush()根本不会改变问题。没效果。
答案 0 :(得分:1)
回应你对我的评论:
public class SMTPServer : IDisposable
{
// all the other stuff
public void Dispose()
{
writer.Dispose();
reader.Dispose();
stream.Dispose();
}
}
调用代码:
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Loopback, 25);
listener.Start();
using (SMTPServer handler = new SMTPServer(listener.AcceptTcpClient()))
{
while (true)
{
Thread thread = new System.Threading.Thread(new ThreadStart(handler.Run));
thread.Start();
}
}
}
答案 1 :(得分:1)
在回答您的实际问题时,您希望阅读所有行,直到您收到。在它自己的一条线上(见https://www.ietf.org/rfc/rfc2821.txt),如下所示: -
var emailLine = reader.ReadLine();
while (!emailLine.Equals("."))
{
// add emailLine to the email body
emailLine = reader.readLine();
}
writer.WriteLine("250 OK");
reader.Close();
writer.Close();
stream.Dispose();