我必须实现IMAP,才能通过C#和.NET Standard 2.0在我自己的电子邮件客户端中使用它。在任务期间,我可以使用 TcpClient 和 SslStream 类。问题在于从服务器获得响应。我找不到如何识别消息结尾的常见解决方案。例如SMTP在每封邮件的末尾都有"\r.\r",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 + "rn");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Console.WriteLine(ReceiveResponse("$ LOGOUTrn"));
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(" ", "");
sb.Append(str);
if (/* PATTERN I NEED*/) break;
}
Console.WriteLine(sb.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return sb.ToString();
}
}
如您所知,我需要该模式来识别消息的单声结尾,或者至少解决如何从IMAP服务器获取完整消息。
附言我的母语不是英语,如果你能用简单的语言表达你的thougth,那就太好了。提前谢谢。
IMAP响应要么是一行,要么是n节加一行。四种响应只是一行:OK,再见,否和坏。其他部分是 n 个部分,其中每个部分是一行以 {number} 结尾,后跟该字节数,最后一行不以 {number} 结尾。
RFC 3501 第 80 页上的示例清楚地显示了这两种类型。请注意,即使是单行也可能很长,在实践中也比 1024 字节长得多。从第 81 页开始的正式语法描述了详细信息;我故意省略了一些细节。