2010-10-05 62 views
2

我一直試圖訪問我的GMail帳戶以從我的電子郵件帳戶中檢索未讀郵件。但是,我只能執行登錄...之後的任何操作都不起作用。使用C#將IMAP命令發送給GMail

首先我連接到服務器,然後發送登錄命令,最後發送檢查命令。問題是,接收到的響應僅指連接和登錄。之後,它只是停止等待某些從StreamReader讀取數據。

try 
     { 
      // create an instance of TcpClient 
      TcpClient tcpclient = new TcpClient(); 
      // HOST NAME POP SERVER and gmail uses port number 995 for POP 
      //tcpclient.Connect("pop.gmail.com", 995); 
      tcpclient.Connect("imap.gmail.com", 993); 
      // This is Secure Stream // opened the connection between client and POP Server 
      SslStream sslstream = new SslStream(tcpclient.GetStream()); 
      // authenticate as client 

      sslstream.AuthenticateAsClient("imap.gmail.com"); 

      bool flag = sslstream.IsAuthenticated; // check flag 
      // Asssigned the writer to stream 
      System.IO.StreamWriter sw = new StreamWriter(sslstream); 
      // Assigned reader to stream 
      System.IO.StreamReader reader = new StreamReader(sslstream); 

      sw.WriteLine("tag LOGIN [email protected] pass"); 
      sw.Flush(); 

      sw.WriteLine("tag2 EXAMINE inbox"); 
      sw.Flush(); 

      sw.WriteLine("tag3 LOGOUT "); 
      sw.Flush(); 

      string str = string.Empty; 
      string strTemp = string.Empty; 
      try 
      { 
       while ((strTemp = reader.ReadLine()) != null) 
       { 
        Console.WriteLine(strTemp); 
        // find the . character in line 
        if (strTemp == ".") 
        { 
         //reader.Close(); 
         break; 
        } 
        if (strTemp.IndexOf("-ERR") != -1) 
        { 
         //reader.Close(); 
         break; 
        } 
        str += strTemp; 
       } 
      } 
      catch (Exception ex) 
      { 
       string s = ex.Message; 
      } 
      //reader.Close(); 

     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
+0

(下旬也許有一點,但最後一個協議級的答案...) – dkarp 2011-02-05 17:23:16

回答

1

你可能看使用罐裝IMAP/SSL庫,而不是 - 有一個是仍然活躍here

This alternative不是免費的。

其中之一的基礎有source code that might be helpful,因爲您要推出自己的協議處理程序。

+0

我已經知道這兩個,但我的主要目的是學習如何與IMAP服務器進行通信... – 2010-10-05 14:26:44

+0

@Miguel - 感謝您的澄清,請參閱編輯 – 2010-10-05 14:33:49

1

你的問題是你期待來自IMAP服務器的POP響應。 POP通過.終止提取的消息,並以其他命令作出響應,其中一行以+OK-ERR開頭。 IMAP不會。您正在消耗所有服務器響應,然後掛起,等待某些內容匹配類似POP的響應解析器。如果您檢查返回的數據,您應該看到服務器對您的(正確格式化)請求的響應的其餘部分。

有可能服務器不是迴應您的第二個和第三個命令的迴應。這可能是因爲你試圖管理三個請求;也就是說,您正在發送請求而無需等待響應。服務器是obliged to allow pipelining while in the SELECTED state,但協議並不保證您可以從NOT AUTHENTICATED狀態管道命令。

+1

另外,LOGOUT命令中的尾部空格不被允許,並且可能會導致一個'tag3 BAD ...'響應。 – dkarp 2011-02-04 23:17:11

2

我一直在尋找這種「Hello World」的例子來讓我開始。隨着dkarp的答案的幫助,這是我採取的米格爾的例子:

 static void Main(string[] args) { 
     try { 
      TcpClient tcpclient = new TcpClient(); 
      tcpclient.Connect("imap.gmail.com", 993); 

      SslStream sslstream = new SslStream(tcpclient.GetStream()); 
      sslstream.AuthenticateAsClient("imap.gmail.com"); 

      if (sslstream.IsAuthenticated) { 
       StreamWriter sw = new StreamWriter(sslstream); 
       StreamReader sr = new StreamReader(sslstream); 

       sw.WriteLine("tag LOGIN [email protected] pass"); 
       sw.Flush(); 
       ReadResponse("tag", sr); 

       sw.WriteLine("tag2 EXAMINE inbox"); 
       sw.Flush(); 
       ReadResponse("tag2", sr); 

       sw.WriteLine("tag3 LOGOUT"); 
       sw.Flush(); 
       ReadResponse("tag3", sr); 
      } 
     } 
     catch (Exception ex) { 
      Console.WriteLine(ex.Message); 
     } 
    } 

    private static void ReadResponse(string tag, StreamReader sr) { 
     string response; 

     while ((response = sr.ReadLine()) != null) { 
      Console.WriteLine(response); 

      if (response.StartsWith(tag, StringComparison.Ordinal)) { 
       break; 
      } 
     } 
    }