2009-11-12 163 views
1

我正在編寫一個測試電子郵件地址的應用程序,我需要發送少量數據到電子郵件地址以完全驗證它的一部分,我目前使用套接字來實現這一點。C#SMTP套接字問題

雖然我正在測試我使用了一個朋友的SMTP服務器進行測試,並且我的套接字工作正常,但是當我在一個大的電子郵件提供商(gmail,hotmail等)上嘗試同樣的事情時,卻沒有它。

現在我得出結論,認證和安全相關,所以我測試了使用StlEnabled內建的SmtpClient和各種Mail對象中的.Nets發送一條消息給gmail,並給它提供它要求的憑證,上班。

我需要做到的是:

,而無需提供登錄信息純粹作爲交換髮送這個數據。 也是一種將Ssl安全性融入到我的套接字中的方法。

任何這方面的幫助將是偉大的和appriciated!下面的代碼...

/// <summary> 
    /// Opens up the socket and begins trying to connect to the provided domain 
    /// </summary> 
    /// <param name="domain">The domain listening on SMTP ports</param> 
    /// <param name="recipient">The email recipient</param> 
    /// <returns>Bool verifying success</returns> 
    public static bool ActivateSocket(string domain, string recipient) 
    { 
     //X509Certificate cert = new X509Certificate(); 

     //Prepare our first command 
     string SMTPcommand = "HELO www.codegremlin.co.uk\r\n"; 
     Encoding ASCII = Encoding.ASCII; 
     //convert to byte array and get the buffers ready 
     Byte[] ByteCommand = ASCII.GetBytes(SMTPcommand); 
     Byte[] RecvResponseCode = new Byte[3]; 
     Byte[] RecvFullMessage = new Byte[256]; 
     //method response value 
     bool TransactionSuccess = false; 



     try 
     { 
      // do all of this outside so its fresh after every iteration 
      Socket s = null; 
      IPEndPoint hostEndPoint; 
      IPAddress hostAddress = null; 
      int conPort = 587; 

      // get all the ip's assosciated with the domain 
      IPHostEntry hostInfo = Dns.GetHostEntry(domain); 
      IPAddress[] IPaddresses = hostInfo.AddressList; 

      // go through each ip and attempt a connection 
      for (int index = 0; index < IPaddresses.Length; index++) 
      { 
       hostAddress = IPaddresses[index]; 
       // get our end point 
       hostEndPoint = new IPEndPoint(hostAddress, conPort); 

       // prepare the socket 
       s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
       s.ReceiveTimeout = 2000; 
       s.SendTimeout = 4000; 
       try { s.Connect(hostEndPoint); } 
       catch { Console.WriteLine("Connection timed out..."); } 

       if (!s.Connected) 
       { 
        // Connection failed, try next IPaddress. 
        TransactionSuccess = false; 
        s = null; 
        continue; 
       } 
       else 
       { 
        // im going through the send mail, SMTP proccess here, slightly incorrectly but it 
        //is enough to promote a response from the server 

        s.Receive(RecvFullMessage); 
        Console.WriteLine(ASCII.GetString(RecvFullMessage)); 

        s.Send(ByteCommand, ByteCommand.Length, 0); 
        s.Receive(RecvFullMessage); 
        Console.WriteLine(ASCII.GetString(RecvFullMessage)); 

        ByteCommand = ASCII.GetBytes("MAIL FROM:[email protected]\r\n"); 
        s.Send(ByteCommand, ByteCommand.Length, 0); 
        s.Receive(RecvFullMessage); 
        Console.WriteLine(ASCII.GetString(RecvFullMessage)); 

        ByteCommand = ASCII.GetBytes("RCPT TO:[email protected]\r\n"); 
        s.Send(ByteCommand, ByteCommand.Length, 0); 
        s.Receive(RecvFullMessage); 
        Console.WriteLine(ASCII.GetString(RecvFullMessage)); 

        ByteCommand = ASCII.GetBytes("DATA\r\n"); 
        s.Send(ByteCommand, ByteCommand.Length, 0); 
        s.Receive(RecvFullMessage); 
        Console.WriteLine(ASCII.GetString(RecvFullMessage)); 

        ByteCommand = ASCII.GetBytes("this email was sent as a test!\r\n.\r\n"); 
        s.Send(ByteCommand, ByteCommand.Length, 0); 
        s.Receive(RecvFullMessage); 
        Console.WriteLine(ASCII.GetString(RecvFullMessage)); 

        ByteCommand = ASCII.GetBytes("SEND\r\n"); 
        s.Send(ByteCommand, ByteCommand.Length, 0); 
        s.Receive(RecvFullMessage); 
        Console.WriteLine(ASCII.GetString(RecvFullMessage)); 

        ByteCommand = ASCII.GetBytes("QUIT\r\n"); 
        s.Send(ByteCommand, ByteCommand.Length, 0); 
        s.Receive(RecvFullMessage); 
        Console.WriteLine(ASCII.GetString(RecvFullMessage)); 

        int i = 0; 
        TransactionSuccess = true; 
       } 

      } 


     } 

     catch (SocketException e) 
     { 
      Console.WriteLine("SocketException caught!!!"); 
      Console.WriteLine("Source : " + e.Source); 
      Console.WriteLine("Message : " + e.Message); 
     } 
     catch (ArgumentNullException e) 
     { 
      Console.WriteLine("ArgumentNullException caught!!!"); 
      Console.WriteLine("Source : " + e.Source); 
      Console.WriteLine("Message : " + e.Message); 
     } 
     catch (NullReferenceException e) 
     { 
      Console.WriteLine("NullReferenceException caught!!!"); 
      Console.WriteLine("Source : " + e.Source); 
      Console.WriteLine("Message : " + e.Message); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Exception caught!!!"); 
      Console.WriteLine("Source : " + e.Source); 
      Console.WriteLine("Message : " + e.Message); 
     } 

     return TransactionSuccess; 

    } 
+0

對不起,刪除我的帖子,因爲它是不準確的。感謝您的更正,@Daniel A. White和@Storm – David 2009-11-12 14:18:34

+0

嗨,這段代碼的目的是什麼?它看起來像垃圾郵件目的的郵件列表清理程序。無論哪種方式,我建議你看看你從你連接的服務器收到的錯誤,並從中推導出解決方案。如果沒有明確指出問題,很難提出解決方案。 – Lazarus 2009-11-12 14:19:47

+0

目的是純粹的電子郵件驗證,即時通訊對垃圾郵件的戰爭的好方面:P – DevlopingTheNextGen 2009-11-12 14:26:12

回答

2

爲什麼你正試圖自己實現這個功能?

您應該重新使用現有的SMTP實現,否則您將永遠無法正確實施大量RFC的所有細節。

我建議你再看看SmtpClient類,因爲它看起來完全符合你的要求。

還有一件事:你知道這個事實,你需要與gmail地址交談的SMTP服務器不是gmail.com,對吧?您需要從DNS檢索gmail.com的MX記錄並連接到其中一個。

除此之外,您不應該直接連接到任何SMTP來傳遞郵件。如果服務器執行重定向列表和其他垃圾郵件技術,您將不會成功。依靠系統上的MTA發送電子郵件。如果您正在執行此操作來檢查電子郵件地址的正確性,則需要提供一個可用的FROM地址並檢查該郵箱是否從MTA中跳出。

+0

感謝您的快速響應我會解決這些問題,讓你知道! – DevlopingTheNextGen 2009-11-12 14:26:55