如何从IMAP服务器

时间:2018-05-01 11:37:30

标签: c# ssl tcp imap .net-standard-2.0

我必须通过C#和.NET Standard 2.0在我自己的电子邮件客户端中实现IMAP。在任务期间,我可以使用TcpClient和SslStream类。问题在于从服务器获得响应。我找不到如何识别消息结束的通用解决方案。比如SMTP有" \ r \ n。\ r \ n"在每条消息的最后,IMAP没有相同的模式(根据我的研究)。大多数IMAP邮件以[TAG] [RESPONSE]结尾,例如A1 OK success,但有些邮件以* OK Gimap...* BAD Invalid...结尾。我刚写了几行代码:

class Program
{
    static TcpClient tcp;
    static SslStream ssl;

    static void Main(string[] args)
    {
        tcp = new TcpClient("imap.gmail.com", 993);
        ssl = new SslStream(tcp.GetStream());
        ssl.AuthenticateAsClient("imap.gmail.com");

        ReceiveResponse("");
        while (true)
        {
            try
            {
                string query = Console.ReadLine();
                if (query == "exit") break;
                ReceiveResponse(query + "\r\n");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            } 
        }

        Console.WriteLine(ReceiveResponse("$ LOGOUT\r\n"));
        Console.ReadKey();
    }

    static string ReceiveResponse(string query)
    {
        StringBuilder sb = new StringBuilder();
        try
        {
            if (query != "")
            {
                if (tcp.Connected)
                {
                    byte[] dummy = Encoding.ASCII.GetBytes(query);
                    ssl.Write(dummy, 0, dummy.Length);
                }
                else
                {
                    throw new ApplicationException("TCP CONNECTION DISCONNECTED!!");
                }
            }
            ssl.Flush();

            byte[] buffer = new byte[1024];
            List<byte> response = new List<byte>();
            while (true) // ваш метод, который определит полный ответ
            {
                int bytesRead = ssl.Read(buffer, 0, 1024);
                if (bytesRead == 0)
                    throw new EndOfStreamException("err");
                string str = Encoding.UTF8.GetString(buffer).Replace("\0", "");
                sb.Append(str);
                if (/* PATTERN I NEED*/) break;
            }

            Console.WriteLine(sb.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return sb.ToString();
    }
}

如您所知,我需要使用该模式来识别消息的单义结尾,或者至少解决如何从IMAP服务器获取完整消息的方法。

P.S。我不是英语母语人士,如果你能用简单的语言表达你的思想,那就太好了。提前谢谢。

1 个答案:

答案 0 :(得分:2)

IMAP响应是一行,或n部分加一行。四种反应只有一行:OK,BYE,NO和BAD。其他部分是n个部分,其中每个部分是以{number}结尾的行,后跟该字节数,以及一个不以{number}结尾的最后一行。

page 80 of RFC 3501上的示例清楚地显示了这两种情况。请注意,即使单行也可能很长,实际上比1024字节长得多。 formal syntax starting on page 81描述了细节;我故意遗漏了一些细节。