开发者

Send IMAP commands to GMail using C#

开发者 https://www.devze.com 2023-01-19 05:32 出处:网络
I\'ve been trying to access my GMail accoun开发者_JAVA百科t to retrieve the unread emails from my email account. However, I only con perform login... Anything after that doesn\'t work.

I've been trying to access my GMail accoun开发者_JAVA百科t to retrieve the unread emails from my email account. However, I only con perform login... Anything after that doesn't work.

First of all I connect to the server, then send the login command and finally the examine command. The thing is that the responses that are receive refers only to the connection and to the login. After that, it just stops waiting for someting to read from the 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 user@gmail.com 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);
        }


I was looking for just this sort of "Hello World" example to get me started. With the help of dkarp's answers, here's my take on Miguel's example:

        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 user@gmail.com 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;
            }
        }
    }


You might look at using a canned IMAP/SSL library instead - there is one that is still active here.

This alternative is not free.

The basis for one of these has source code that might be helpful since you want to roll your own protocol handler.


Your problem is that you're expecting POP responses from an IMAP server. POP terminates fetched messages with . and responds to other commands with a line beginning with either +OK or -ERR. IMAP doesn't. You're consuming all the server responses and then hanging, waiting for something to match your POP-like response parser. If you examine the returned data, you should see the remainder of the server's responses to your (properly-formatted) requests.

There is a possibility that the server isn't sending back responses to your second and third commands. This could be because you're trying to pipeline three requests; that is, you're sending the requests without waiting for the responses. The server is obliged to allow pipelining while in the SELECTED state, but the protocol doesn't guarantee that you can pipeline commands from the NOT AUTHENTICATED state.

0

精彩评论

暂无评论...
验证码 换一张
取 消