2012-04-25 23 views
2

私は単純なGmailクライアントをやろうとしています。問題は、私がかなり奇妙な応答を得ていることです。実際に私はSslStream.readからの応答を全く得ていません。まず、私はクライアントとしてGmailのサーバーに接続するとき、それは完璧に動作します(Connect()法)が、私は再びleerMensaje()方法でSslStream.readを使用して、数オフメールを取得しようとしているときに、それは奇妙な取得し、単に実行を停止し、そしてウェブページに負荷がかかってしまいます。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 Webページです:

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"); 
      } 
     } 
    } 

答えて

1

最初の問題は、あなたが「STATを送っているということである。ここ

は、私が働いているクラスです。 "をコマンドとして使用することができますが、すべてのコマンドは" \ r \ n "で終了する必要がありますので、代わりに" STAT \ r \ n "を送信する必要があります。

sslStream.Read(...)からの戻りコード0でメッセージの終わりを推測しているようですが、このメソッドはストリームが閉じられるまで0を返しません。読み込み待ちのデータがなくなった場合は、Read()がブロックされ、より多くのデータが到着するのを待って、表示されているハングを説明します。

POP3 protocol specificationによれば、1行の応答では、応答の終わりを示す「\ r \ n」シーケンスと、複数行の応答となるコマンド(たとえば、検索メッセージデータ)、応答は単一の "。"で終了します。 (つまり、行は "。\ r \ n"で始まります)。この終了シーケンスを含むメッセージを処理するための追加の規則がありますので、私はあなた自身でプロトコル仕様を読むことをお勧めします。

+0

うん、私はあなたが言ってみてください、そして実際に私がreadメソッドのドキュメントの前に読んで、それが読み込んだバイトオフ番号を返すので、それがラインオフ最後に、それは0を返す必要がある場合は、問題があることですプログラムが最初に到達したときにプログラムをデバッグしても、その行を実行した直後にデバッグを停止するだけです。かなり奇妙な行動です。 –

+0

Read()を初めて呼び出すと、コマンドが "\ r \ n"で終了する必要があるためです。あなたは単に "STAT"を送信していますが、代わりに "STAT \ r \ n"を送信する必要があります。私はこれを反映するために私の答えを編集します。しかし、私の元の答えはまだ立っている - 現在のコードはRead()が0を返すことを期待しているので(接続が閉じられていない限り)、コマンドを正しく送信してもハングしますが、代わりにRead()を呼び出す必要があります。 – Iridium

+0

ありがとうございました、クラスの後で真夜中に働いているので、私たちが時々見られないような小さなデータイル。再度、感謝します –

関連する問題