我正在嘗試做一個簡單的Gmail客戶端。問題是我得到一個非常奇怪的迴應;其實我根本沒有得到SslStream.read
的迴應。首先,當我以客戶端身份連接到Gmail服務器時,它的工作原理非常完美(Connect()
方法),但是當我嘗試從電子郵件中獲取號碼時,再次使用SslStream.read
和leerMensaje()
方法,它變得很奇怪,只是停止運行,網頁卡住加載。沒有得到SslStream.read的響應
這裏是我工作類:
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");
}
}
}
是的,我嘗試了你所說的,實際上我在read方法的文檔之前閱讀,並且它返回讀取的字節數,所以如果它在結束時應該返回0,問題是甚至在程序第一次達到該指令時調試程序,它只是在它運行該程序後立即停止調試。是一個很奇怪的行爲。 – 2012-04-25 11:55:32
第一次調用Read()時掛起的原因是因爲命令必須以「\ r \ n」結尾。你只是發送「STAT」,但需要發送「STAT \ r \ n」。我將編輯我的答案以反映這一點。但是我的原始答案仍然存在 - 因爲當前代碼仍然期望Read()返回0(除非連接已關閉,否則它不會),所以即使您正確發送命令,它仍然會掛起,但是在第二次調用Read()。 – Iridium 2012-04-25 13:05:51
謝謝你,我們有時候看不到的那些小聾人,因爲你們正在上課後的午夜。再次感謝 – 2012-04-25 19:16:21