自动刷新tcp流不起作用

时间:2014-10-27 12:27:46

标签: c# tcp tcpclient flush

您可能会看到我使用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()根本不会改变问题。没效果。

2 个答案:

答案 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();