C# 未从SslStream.read获取响应

C# 未从SslStream.read获取响应,c#,asp.net,ssl,gmail,C#,Asp.net,Ssl,Gmail,我正在尝试做一个简单的Gmail客户端。问题是我得到了一个非常奇怪的回答;实际上,我没有收到来自SslStream.read的响应。首先,当我作为客户端连接到gmail服务器时,它工作得很好(connect()方法),但当我试图从电子邮件中获取号码时,再次使用SslStream.read使用leerMensaje()方法,它会变得很奇怪,只是停止运行,网页无法加载 以下是我正在学习的课程: using System; using System.Collections.Generic; using

我正在尝试做一个简单的Gmail客户端。问题是我得到了一个非常奇怪的回答;实际上,我没有收到来自
SslStream.read的响应。首先,当我作为客户端连接到gmail服务器时,它工作得很好(
connect()
方法),但当我试图从电子邮件中获取号码时,再次使用
SslStream.read
使用
leerMensaje()
方法,它会变得很奇怪,只是停止运行,网页无法加载

以下是我正在学习的课程:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Text;
using System.Net.Mail;

namespace GmailClient
{
    public class GmailPop
    {
        private SslStream sslStream;
        private String user;
        private String pass;

        public GmailPop(String user, String pass)
        {
            this.user = user;
            this.pass = pass;
        }

        public bool Connect()
        {
            String response;
            byte[] buffer = new byte[2048];
            int bytes = -1;
            TcpClient server = new TcpClient("pop.gmail.com", 995);
            sslStream = new SslStream(server.GetStream());
            sslStream.AuthenticateAsClient("pop.gmail.com");
            bytes = sslStream.Read(buffer, 0, buffer.Length);
            response = Encoding.ASCII.GetString(buffer,0,bytes);
            sslStream.Write(Encoding.ASCII.GetBytes("USER recent:" + user+"\r\n"));
            bytes = sslStream.Read(buffer, 0, buffer.Length);
            response = Encoding.ASCII.GetString(buffer,0,bytes);
            if(response.StartsWith("+OK")){
                sslStream.Write(Encoding.ASCII.GetBytes("PASS "+pass+"\r\n"));
                bytes = sslStream.Read(buffer,0,buffer.Length);
                response = Encoding.ASCII.GetString(buffer, 0, bytes);
                return response.StartsWith("+OK");
            }
            return false;
        }
        public int numCorreos()
        {
            String res = escribirLeer("STAT");
            String[] resA = res.Split(' ');
            int num = Int32.Parse(resA[1]);
            return num;
        }
        public String leerMensaje()
        {
            int bytes = -1;
            byte[] buffer = new byte[2048];
            String msg = "";
            do
            {
                bytes = sslStream.Read(buffer, 0, buffer.Length);
                msg += Encoding.ASCII.GetString(buffer, 0, bytes);
            } while (bytes != 0);
            return msg;
        }
        public void escribirMsg(String msg)
        {
            byte[] buffer = Encoding.ASCII.GetBytes(msg);
            sslStream.Write(buffer);
            sslStream.Flush();
        }
        public String escribirLeer(String msg)
        {
            escribirMsg(msg);
            String respuesta = leerMensaje();
            return respuesta;
        }
    }
}
下面是调用该方法的aspx网页:

GmailPop client;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["user"] != null && Session["pass"] != null)
            {
                String user = Session["user"].ToString();
                String pass = Session["pass"].ToString();

                client = new GmailPop(user, pass);

                if (client.Connect())
                {                    
                    Session["active"] = true;
                    Response.Write(numCorreos());
                }
                else
                {
                    Session.Remove("pass");
                    Response.Redirect("login.aspx?error=login");
                }
            }
            else
            {
                Response.Redirect("login.aspx");
            }
        }
    }

第一个问题是您将“STAT”作为命令发送,但所有命令都必须以“\r\n”结尾,因此您需要改为发送“STAT\r\n”

sslStream.Read(…)
,您似乎也在通过返回代码0推断消息的结尾,但是此方法在流关闭之前不会返回0。在没有更多数据等待读取的情况下,
read()
将阻塞,等待更多数据到达,这解释了您看到的挂起


根据,对于单行响应,您应该等待一个“\r\n”序列来指示响应的结束,对于那些导致多行响应(例如检索消息数据)的命令,响应将由一行上的单个“.”终止(即,该行以“.\r\n”开头)。处理包含此终止序列的消息还有其他规则,因此我建议您自己阅读协议规范。

是的,我尝试了您所说的,实际上我在读取方法的文档之前阅读了,它返回读取的字节数,因此,如果它在行尾返回0,问题是即使在程序第一次到达该指令时进行调试,它也会在运行该行后立即停止调试。是一种非常奇怪的行为。第一次调用Read()时挂起它的原因是命令必须以“\r\n”结尾。您只是发送“STAT”,但需要改为发送“STAT\r\n”。我将编辑我的答案以反映这一点。但是,我的原始答案仍然有效-因为当前代码仍然期望Read()返回0(除非连接关闭,否则它不会返回0),所以即使您正确发送了命令,它仍然会挂起,但在第二次调用Read()时会挂起。谢谢,我们有时看不到的小死亡,因为你课后工作到半夜。再次感谢