Question

I try to receive messages from gmail account but get an error: host not found.

Here is my code:

        using (TcpClient client = new TcpClient("pop.gmail.com ", 995))
        using (NetworkStream n = client.GetStream())
        {
            ReadLine(n);                             // Read the welcome message.
            SendCommand(n, "my_login@gmail.com");
            SendCommand(n, "my_password");
            SendCommand(n, "LIST");                  // Retrieve message IDs
            List<int> messageIDs = new List<int>();
            while (true)
            {
                string line = ReadLine(n);             // e.g.  "1 1876"
                if (line == ".") break;
                messageIDs.Add(int.Parse(line.Split(' ')[0]));   // Message ID
            }

            foreach (int id in messageIDs)         // Retrieve each message.
            {
                SendCommand(n, "RETR " + id);
                string randomFile = Guid.NewGuid().ToString() + ".eml";
                using (StreamWriter writer = File.CreateText(randomFile))
                    while (true)
                    {
                        string line = ReadLine(n);      // Read next line of message.
                        if (line == ".") break;          // Single dot = end of message.
                        if (line == "..") line = ".";    // "Escape out" double dot.
                        writer.WriteLine(line);         // Write to output file.
                    }
                SendCommand(n, "DELE " + id);       // Delete message off server.
            }
            SendCommand(n, "QUIT");
        }

       static void SendCommand(Stream stream, string line)
       {
           byte[] data = Encoding.UTF8.GetBytes(line + "\r\n");
           stream.Write(data, 0, data.Length);
           string response = ReadLine(stream);
           if (!response.StartsWith("+OK"))
               throw new Exception("POP Error: " + response);
       }

Where is my mistake? Also I want do delete some messages from my box. How can I do this?

Thank you very much!

Was it helpful?

Solution

The first problem I see with your code is that it doesn't use an SslStream (needed to connect to GMail's SSL-wrapped POP3 service on port 995).

The second problem I see is

if (line == "..") line = ".";

If you actually bother to read the POP3 specification, you'll discover this:

Responses to certain commands are multi-line. In these cases, which
are clearly indicated below, after sending the first line of the
response and a CRLF, any additional lines are sent, each terminated
by a CRLF pair. When all lines of the response have been sent, a
final line is sent, consisting of a termination octet (decimal code
046, ".") and a CRLF pair. If any line of the multi-line response
begins with the termination octet, the line is "byte-stuffed" by
pre-pending the termination octet to that line of the response.
Hence a multi-line response is terminated with the five octets
"CRLF.CRLF". When examining a multi-line response, the client checks
to see if the line begins with the termination octet. If so and if
octets other than CRLF follow, the first octet of the line (the
termination octet) is stripped away. If so and if CRLF immediately
follows the termination character, then the response from the POP
server is ended and the line containing ".CRLF" is not considered
part of the multi-line response.

This is the important bit: When examining a multi-line response, the client checks to see if the line begins with the termination octet. If so and if octets other than CRLF follow, the first octet of the line (the termination octet) is stripped away.

This means that if the client encounters a line such as "..some text\r\n", the leading '.' needs to be stripped away.

Your code only strips it away if the line exactly matches "..\r\n".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top