如何将smtp消息发送到特定的IP和端口?

时间:2011-03-15 20:20:08

标签: .net smtp

我想测试一个本地服务,它可以监听像12345这样的特定端口,并解析smtp消息部分,例如from,to,body ......

我想为我的监听器制作一个测试工具,并且在创建一些将通过特定端口号生成smtp消息到某个特定IP(我的监听器正在运行的ip /端口)的smtp消息时遇到了麻烦。

我试图通过.net控制台应用程序发送它失败,因为我被迫指定一个smtp服务器发送我的消息,并且由于安全性我不会为此工作。

如果我记得正确我应该能够telnet或以某种方式使用命令行发送电子邮件到IP和端口。基本上我不在乎如何做到这一点只要能够以某种方式向我的听众发送邮件消息。

我的发送应用:

int count = 3;
for (int i = 1; i <= count; i++)
{

    MailMessage message = new MailMessage("sender@ml.com", "recep@ml.com");
    SmtpClient client = new SmtpClient(IPAddress.Loopback.ToString(), 8000);
    message.Body = "test mail #" + i.ToString();
    client.Send(message);

    Console.WriteLine("mail " + i.ToString() + " Sent");
    Console.ReadLine();
}
Console.WriteLine("DONE!");

我的听众应用:

TcpListener listener = new TcpListener(IPAddress.Loopback, 8000);
TcpClient client;
NetworkStream ns;

listener.Start();

Console.WriteLine("Awaiting connection...");
client = listener.AcceptTcpClient();
Console.WriteLine("Connection accepted!");

ns = client.GetStream();

using (StreamWriter writer = new StreamWriter(ns))
{
writer.WriteLine("220 localhost SMTP server ready.");
writer.Flush();

using (StreamReader reader = new StreamReader(ns))
{
    string response = reader.ReadLine();

    if (!response.StartsWith("HELO") && !response.StartsWith("EHLO"))
    {
    writer.WriteLine("500 UNKNOWN COMMAND");
    writer.Flush();
    ns.Close();
    return;
    }

    string remote = response.Replace("HELO", string.Empty).Replace("EHLO", string.Empty).Trim();

    writer.WriteLine("250 localhost Hello " + remote);
    writer.Flush();

    response = reader.ReadLine();

    if (!response.StartsWith("MAIL FROM:"))
    {
    writer.WriteLine("500 UNKNOWN COMMAND");
    writer.Flush();
    ns.Close();
    return;
    }

    remote = response.Replace("RCPT TO:", string.Empty).Trim();
    writer.WriteLine("250 " + remote + " I like that guy too!");
    writer.Flush();

    response = reader.ReadLine();

    if (!response.StartsWith("RCPT TO:"))
    {
    writer.WriteLine("500 UNKNOWN COMMAND");
    writer.Flush();
    ns.Close();
    return;
    }

    remote = response.Replace("MAIL FROM:", string.Empty).Trim();
    writer.WriteLine("250 " + remote + " I like that guy!");
    writer.Flush();

    response = reader.ReadLine();

    if (response.Trim() != "DATA")
    {
    writer.WriteLine("500 UNKNOWN COMMAND");
    writer.Flush();
    ns.Close();
    return;
    }

    writer.WriteLine("354 Enter message. When finished, enter \".\" on a line by itself");
    writer.Flush();

    int counter = 0;
    StringBuilder message = new StringBuilder();

    while ((response = reader.ReadLine().Trim()) != ".")
    {
    message.AppendLine(response);
    counter++;

    if (counter == 1000000)
    {
        ns.Close();
        return;  // Seriously? 1 million lines in a message?
    }
    }

    writer.WriteLine("250 OK");
    writer.Flush();
    ns.Close();
    // Insert "message" into DB
    Console.WriteLine("Received message:");
    Console.WriteLine(message.ToString());
}
}

Console.ReadKey();

1 个答案:

答案 0 :(得分:0)

您必须指定的SMTP地址和端口是您要测试的应用程序的地址和端口。

SMTP上的电子邮件在大多数情况下从服务器转发到服务器而不进行任何修改并使用相同的传输协议。因此,您直接向您的应用程序或中继服务器(如ISP的电子邮件服务器)提供的内容对发件人来说并不重要。它没有看到任何区别。

不同之处在于您的ISP服务器可能无法将电子邮件中继到您的应用程序,因为它需要DNS中的MX记录并正确防火墙/端口转发到您的应用程序。

您甚至可以在Outlook中配置SMTP配置文件以直接发送到您的应用程序。只需将app ip和port指定为SMTP服务器即可。

使用telnet:

telnet ip port
helo me
mail from: <some@domain.com>
rcpt to: <some@domain.com>
data
Subject: Ho Ho Ho
From: Santa 

Hello!
.

服务器将确认您输入的每一行,通常是英文文本。

请注意标题和正文之间的空行,以及最后一行结束消息的单点。