2015-12-17 28 views
0

我有一个应用程序扫描电子邮件帐户的返回邮件。它使用POP3,并在多个客户端系统上成功运行。但是,对于一个客户端,当我们尝试连接时,我们得到一个SocketException - 没有这样的主机是已知的。使用POP3连接到SSL

我的第一个想法是无论是地址还是端口都无法访问,但他们回来说它是一个SSL端口,我认为我的代码可能无法处理SSL。但是,当我打电话给tcpClient = new TcpClient(Host, Port);时,发生错误,所以我回到了我以前的假设。 TcpClient需要连接到SSL端口的特殊方式吗?

我的第二个问题是,是否有一种简单的方法可以将代码转换为使用SSL,而无需创建常规的POP3连接类和SSL POP3连接类?我相信我需要使用SslStream而不是StreamReader,这意味着我将不得不修改任何访问POP3服务器的代码,因为SslStream没有ReadLine()方法。

我在下面添加了我的初始连接代码(或重要位)。

try 
{ 
    tcpClient = new TcpClient(Host, Port); 
} 
catch (SocketException e) 
{ 
    logger.Log(...); 
    throw (e); 
} 
String response = ""; 

try 
{ 
    streamReader = new StreamReader(tcpClient.GetStream()); 

    // Log in to the account 
    response = streamReader.ReadLine(); 
    if (response.StartsWith("+OK")) 
    { 
     response = SendReceive("USER ", UserName.Trim() + "@" + Domain.Trim()); 
     if (response.StartsWith("+OK")) 
     { 
      response = SendReceive("PASS ", Password); 
     } 
    } 

    if (response.StartsWith("+OK")) 
     result = true; 
} 
catch (Exception e) 
{ 
    result = false; 
} 

SendReceive方法很简单:

private String SendReceive(String command, String parameter) 
{ 
    String result = null; 
    try 
    { 
     String myCommand = command.ToUpper().Trim() + " " + parameter.Trim() + Environment.NewLine; 
     byte[] data = System.Text.Encoding.ASCII.GetBytes(myCommand.ToCharArray()); 
     tcpClient.GetStream().Write(data, 0, data.Length); 
     result = streamReader.ReadLine(); 
    } 
    catch { } // Not logged in... 
    return result; 
} 

这似乎是主要的ReadLine()方法不起作用,但在看完了顾名思义是难以阅读与线因为你不知道它是否发送完毕。是这样的,还是我只需要写一个快速的方法来阅读,直到我打到\r\n

回答

1

要回答你的第一个问题,没有什么不同的方式连接到SSL端口,它的工作方式完全相同。

至于你的第二个问题,一个StreamReader封装了System.IO.StreamSslStream只是System.IO.Stream的实现,这样你就可以创建它周围的StreamReader就好了。

,你需要做的是这样的:

var stream = tcpClient.GetStream(); 

if (useSsl) { 
    var ssl = new SslStream (stream); 
    ssl.AuthenticateAsClient (Host, null, SslProtocols.Tls12, true); 
    stream = ssl; 
} 

streamReader = new StreamReader (stream); 

当然,你需要修复您的SendReceive()方法无法再次使用tcpClient.GetStream(),因为你需要使用SslStream和而不是NetworkStreamtcpClient.GetStream()将返回。

做到这一点的最简单的方法可能是在stream变量只是传递给SendReceive(),或者,我想,一个Stream成员添加到您的类像你大概是streamReadertcpClient一样。

当然,一个更好的解决办法是使用库这个功能,比如我MailKit库,它负责处理所有这一切为您在更强大的方式比这个代码:)

+0

尝试使用Tls10或Tls11 ,也许GMail不支持TLS v1.2。另外,GMail不支持USER/PASS;它只支持SASL AUTH。 – jstedfast