0

I am working on an email client that will connect to Gmail mailbox and retrieve a specific email.

Now i can connect to my mailbox and can retrieve part of the emails not all of it and no matter how large is my buffer still i get only 1400 char from my email and then Null for the rest of the mail body.

You can find a screen shot for the email body in this link

http://www.elzouhery.com/Mail%20Snapshot.png

Thanks in Advance

EDIT

See below the Full Code

    static void Main(string[] args)
        {
            TcpIMAP imap = ConnectToEmail();
            Console.WriteLine("Total Messages " + imap.MailCount());
            Console.WriteLine("Total Unread Messages " + imap.MailUnreadCount());
            Console.WriteLine("******************************************************");
            imap.SelectInbox();

            StreamWriter writer = null;
            int mailCount = imap.MailCount();
            var mailSize = string.Empty;
            var content = string.Empty;
            var subject = string.Empty;


            for (int i = 1; i < mailCount; i++)
            {
                try
                {
                    writer = new StreamWriter(@"c:\Mails\" + i + ".txt", true);
                    content = imap.GetMessage(i).ToString();
                    writer.Write(content);
                    writer.Close();
                }
                catch(Exception ex)
                {
                    writer.Write(content);
                    Console.Write(ex.Message);
                    writer.Close();
                }
            }
        }

        private static TcpIMAP ConnectToEmail()
        {
            string host = "imap.gmail.com";
            string username = "************";
            string password = "************";

            TcpIMAP imap = new TcpIMAP();
            imap.Connect(host, 993);
            imap.AuthenticateUser(username, password);
            return imap;
        }

        public static string GetMailSubject(string Header)
        {
            var headerLines = Header.Split(Environment.NewLine.ToCharArray());
            foreach (var line in headerLines)
            {
                if (line.IndexOf("Subject") > -1)
                {
                    return line.Replace("Subject: ", "");
                }
            }
            return "";
        }
/***************************************************/
class TcpIMAP
{
    private TcpClient _imapClient;
    private Stream _imapNs;
    private StreamWriter _imapSw;
    private StreamReader _imapSr;

    public TcpIMAP()
    {

    }

    public TcpIMAP(string hostname, int port)
    {
        InitializeConnection(hostname, port);
    }

    public void Connect(string hostname, int port)
    {
        InitializeConnection(hostname, port);
    }

    private void InitializeConnection(string hostname, int port)
    {
        try
        {
            _imapClient = new TcpClient(hostname, port);
            System.Net.Security.SslStream sslstream = new System.Net.Security.SslStream(_imapClient.GetStream());
            sslstream.AuthenticateAsClient("imap.gmail.com");
            _imapNs = sslstream;
            _imapSw = new StreamWriter(_imapNs);
            _imapSr = new StreamReader(_imapNs);

            Console.WriteLine("*** Connected ***");
            Response();
        }
        catch (SocketException ex)
        {
            Console.WriteLine(ex.Message);
        }
    }


    public void AuthenticateUser(string username, string password)
    {
        _imapSw.WriteLine("$ LOGIN " + username + " " + password);
        _imapSw.Flush();
        Response();
    }


    public int MailCount()
    {
        _imapSw.WriteLine("$ STATUS INBOX (messages)");
        _imapSw.Flush();

        string res = Response();
        Match m = Regex.Match(res, "[0-9]*[0-9]");
        return Convert.ToInt32(m.ToString());
    }

    public int MailUnreadCount()
    {
        _imapSw.WriteLine("$ STATUS INBOX (unseen)");
        _imapSw.Flush();

        string res = Response();
        Match m = Regex.Match(res, "[0-9]*[0-9]");
        return Convert.ToInt32(m.ToString());
    }


    public string SelectInbox()
    {
        _imapSw.WriteLine("$ SELECT INBOX");
        _imapSw.Flush();
        return Response();
    }


    public object GetMessageHeaders(int index)
    {
        _imapSw.WriteLine("$ FETCH " + index + " (body[header.fields (from subject date)])");
        _imapSw.Flush();

        return Response();
    }

    public object GetMessage(int index)
    {
        _imapSw.WriteLine("$ FETCH " + index + " BODY.PEEK[]");
        _imapSw.Flush();

        return Response();
    }
    private string Response()
    {
        byte[] data = new byte[_imapClient.ReceiveBufferSize];
        int ret = _imapNs.Read(data, 0, data.Length);
        string output = Encoding.ASCII.GetString(data).TrimEnd().Replace("\0", "");
        return output;
    }



    public void Disconnect()
    {
        _imapSw.WriteLine("$ LOGOUT");
        _imapSw.Flush();
        _imapClient.Close();
    }

    public string SendCommand(string command)
    {
        _imapSw.WriteLine("$ " + command);
        _imapSw.Flush();
        return Response();
    }
  • Post code please. Sounds like you are only getting the first packet of the email back. – Joe Jul 11 '12 at 16:23
  • What is _imapClient, and what is setting ReceiveBufferSize? I'm guessing you have to call that repeatedly, based on some other event/trigger. – Joe Jul 12 '12 at 11:08
  • Calling these functions retrieve only part of the message if its a long one and not all of it no matter how large the buffer is, i included the full code in edit above – Mahmoud Ali El-Zouhery Jul 12 '12 at 11:42
  • @leppie, well I did ask for it... – Joe Jul 13 '12 at 19:44

2 Answers2

0

It looks like you are using code from here, or similar:

http://www.codeproject.com/Articles/29594/How-to-Access-Emails-Using-the-IMAP-Protocol

That code as written is wrong and won't work for larger messages. The Response() call needs to loop over calls to .Read(), appending the results until the method returns 0 (which indicates there is no more data available.) Look at the documentation for NetworkStream.Read.

Also, you'd be much better off using an IMAP library (see Accessing Imap in C#).

Community
  • 1
  • 1
Joe
  • 41,484
  • 20
  • 104
  • 125
  • Yes i used the code you mentioned above and i tried to loop over read to load the whole message body but to be able to read i have to send a command to server, for example i had to send STATE command in a loop till I see OK Success which detrmine that the message is completed but it was buggy so i thought there might be away to get the whole message body in 1 call – Mahmoud Ali El-Zouhery Jul 12 '12 at 14:06
  • Also the link you sent is not working do you have alternative link for it http://hellowebapps.com/products/imapx/ – Mahmoud Ali El-Zouhery Jul 12 '12 at 14:09
0

You Just Have To Change Your Receive Buffer Size