Question

I am developing an app with xamarin studio. My goal is to connect to pop3 and download emails to my app. I am using the following code but I am facing these issues: a) an exception on sslstream.AuthenticateAsClient("pop.gmail.com");. (The authentication or decryption has failed). b)everywhere I have sw.Flush() I am taking exception: This operation is invalid until it is successfully authenticated.

TcpClient tcpclient = new TcpClient();
tcpclient.Connect("pop.gmail.com", 995);            
System.Net.Security.SslStream sslstream = new SslStream(tcpclient.GetStream());
sslstream.AuthenticateAsClient("pop.gmail.com"); 
StreamWriter sw = new StreamWriter(sslstream);
System.IO.StreamReader reader = new StreamReader(sslstream); 
sw.WriteLine("USER myusername");  
sw.Flush();
sw.WriteLine("PASS *****");
sw.Flush();
sw.WriteLine("RETR 1");
sw.Flush();
sw.WriteLine("Quit ");
sw.Flush();
string str = string.Empty;
string strTemp = string.Empty;
while((strTemp = reader.ReadLine()) !=null){
    if(".".Equals(strTemp)){
        break;
    }
    if(strTemp.IndexOf("-ERR") != -1){
        break;
    }
    str +=strTemp;
}
reader.Close();
sw.Close();
tcpclient.Close();

EDIT

I used mailkit and it is a great solution. I can retrieve emails but i have a problem. When i have download a number of mails(not specific number. For deferent account was deferent number of mails) I am taking the following error: system.ArgumentOutOfRangeException on: var message = client.GetMessage(i, cancel.Token); My code for the login:

partial void btnlogin (NSObject sender)
{

        using (var client = new Pop3Client ()) {
            var credentials = new NetworkCredential (Convert.ToString(txtusername.Text).Trim(), Convert.ToString(txtpassword.Text).Trim());

            // Note: if the server requires SSL-on-connect, use the "pops" protocol instead
            var uri = new Uri (Convert.ToString("pops://pop.gmail.com"));

            using (var cancel = new CancellationTokenSource ()) {
                client.Connect (uri, cancel.Token);
                client.Authenticate (credentials, cancel.Token);

                int count = client.GetMessageCount (cancel.Token);
                var list= new List<string>();
                for (int i = 0; i < count; i++) {
                    var message = client.GetMessage (i, cancel.Token);
                    Console.WriteLine ("From: {0}", message.From);
                    list.Add(Convert.ToString(message.From));
                }

                client.Disconnect (true, cancel.Token);
            }
        }
                   }
Was it helpful?

Solution

I came here to suggest using MailKit instead of writing your own library for this. MailKit is also specifically meant to work with Xamarin (since I work at Xamarin). MailSystem.NET is pretty badly broken (I've ranted about it elsewhere on StackOverflow), so I would definitely not recommend using that.

That said, you may need to look at using this version of the SslStream .ctor as opposed to the one you are using. The problem may be that the default .ctor isn't validating the SSL certificate because it isn't "trusted".

OTHER TIPS

I would use an existing C# library to do this.

At one point in the past, I used MailSystem.NET and was able to port their library to MonoTouch. I am not sure of its license works for you, but you will have a much better time using it than rolling your own.

I also think that writing your own library for this would be a waste of anyone's time. I haven't tried Mail Kit yet (will definitely have to), but I have recently used Rebex Mail when I needed to backup my emails from my email server via POP3. Fortunatelly, it was a one time task only, so I did not have to pay as I only used their 30-day free trial that did not have any limitation.

        using Rebex.Mail;
        using Rebex.Net;

        Pop3 client = new Pop3();
        client.Connect("pop.gmail.com", SslMode.Implicit);
        client.Login("gmailuser", "password");

        var messageInfos = client.GetMessageList(Pop3ListFields.FullHeaders);
        foreach (Pop3MessageInfo message in messageInfos)
            client.GetMessage(message.SequenceNumber, string.Format(@"C:\gmail-pop3-backup\{0}-{1}.eml", message.Subject, message.UniqueId));

        client.Disconnect();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top