gpt4 book ai didi

c# - 请帮助解决我使用 POP3 协议(protocol)检索电子邮件的问题

转载 作者:太空宇宙 更新时间:2023-11-03 14:36:36 29 4
gpt4 key购买 nike

我正在使用 C# 和 Microsoft .Net Compact Framework 1.0。我尝试使用 System.Net.Sockets.NetworkStream 实现 POP3 协议(protocol)和 TcpClient类。我能够登录并接收电子邮件并使用某些电子邮件服务器保存附件。但对于某些人来说,我一直遇到问题。

我通过发送 List <Index> 来读取电子邮件的大小命令。在某些情况下,我得到的尺寸明显小于实际值。例如,对于同一个电子邮件:

Actual size: 577860, Returned size: 421096 using Exchange 2007
Actual size: 561005, Returned size: 560997 using Exchange 2003

为什么我总是买不到合适的尺寸?以下是我正在使用的代码。

电子邮件的大小永远不会与 StringBuilder 的大小匹配在 PopRead 的末尾程序。我无法可靠地阅读电子邮件,因为电子邮件大小不可靠并且 DataAvailable NetworkStream 的属性(property)有时是错误的,即使有更多的数据可以读取。

我观察到 DataAvailable与通过 activesync 使用计算机的 Internet 连接相比,当我尝试通过无线方式(使用数据计划)连接到电子邮件服务器时,属性更常为 false。

如果有帮助,电子邮件服务器是 Exchange 2003 和 Exchange 2007。

private bool POPRead(StringBuilder strBuffer, long lngFetchMailSize)
{
const int bufferSize = 1024;

byte[] inb;
if (enc == null)
{
enc = new ASCIIEncoding();
}

try
{
if (lngFetchMailSize > 0 && lngFetchMailSize < (32 * bufferSize))
{
// limit the size of the buffer as the amount of memory
// on Pocket PC is limited.
inb = new byte[lngFetchMailSize];
}
else
{
inb = new byte[bufferSize];
}
Array.Clear(inb, 0, inb.Length);
bool bMoreData = true;
long iBytesRead = 0L;
int bytesReadInThisRound = 0;

int numberOfTimesZeroBytesRead = 0;

while (bMoreData)
{
bytesReadInThisRound = this.nsPOP.Read(inb, 0, inb.Length);
iBytesRead += bytesReadInThisRound;

if (bytesReadInThisRound == 0)
{
numberOfTimesZeroBytesRead++;
}
else
{//If on a retry the data read is not empty, reset the counter.
numberOfTimesZeroBytesRead = 0;
}

strBuffer.Append(enc.GetString(inb, 0, bytesReadInThisRound));
Array.Clear(inb, 0, bytesReadInThisRound);
// DataAvailable sometimes gives false even though there is
// more to be read.
bMoreData = this.nsPOP.DataAvailable;
// Use this number (5), since some servers sometimes give the size
// of the email bigger than the actual size.
if ((lngFetchMailSize != 0 && !bMoreData)
&& (iBytesRead < lngFetchMailSize)
&& numberOfTimesZeroBytesRead < 5)
{
bMoreData = true;
}
}
}
catch (Exception ex)
{
string errmessage = "Reading email Expected Size: " + lngFetchMailSize;
LogException.LogError(ex, errmessage, false, "oePPop.POPRead");
Error = ex.Message + " " + errmessage;
return false;
}
finally
{
GC.Collect();
}
return true;
}

以下过程用于获取电子邮件的大小:

private long GetMailSize(int index)
{
StringBuilder strBuffer = new StringBuilder();
const string LISTError = "Unable to read server's reply for LIST command";
if ((this.POPServer != null) && (this.nsPOP != null))
{
if (!this.POPWrite("LIST " + index))
{
return -1L;
}
if (!this.POPRead(strBuffer))
{
this.Error = LISTError;
return -1L;
}
if (!this.IsOK(strBuffer))
{
return -1L;
}
string strReturned = strBuffer.ToString();
int pos1 = strReturned.IndexOf(" ", 3);
if (pos1 == -1)
{
this.Error = LISTError;
return -1L;
}
int pos2 = strReturned.IndexOf(" ", (int)(pos1 + 1));
if (pos2 == -1)
{
this.Error = LISTError;
return -1L;
}
int pos3 = strReturned.IndexOf("\r\n", (int)(pos2 + 1));
if (pos3 == -1)
{
this.Error = LISTError;
return -1L;
}
long mailSize = 0;
Int64.TryParse(strBuffer.ToString(pos2 + 1, pos3 - (pos2 + 1)).Trim(), out mailSize);
return mailSize;
}
this.Error = NotConnectedError;
return -1L;
}

希望我提供了解决问题所需的所有信息。在正确方向上的任何帮助或指示都会有很大帮助。

谢谢,
钱德拉。

最佳答案

您的错误可能在于按您的方式使用 ASCIIEncoder。

来自 MSDN :

Data to be converted, such as data read from a stream, can be available only in sequential blocks. In this case, or if the amount of data is so large that it needs to be divided into smaller blocks, the application should use the Decoder or the Encoder provided by the GetDecoder method or the GetEncoder method, respectively.

由于您一次只解码一点点,因此有可能错误地解码了部分流。

我会更改您的代码以使用 decoder ,或者一次读取整个消息,然后使用 GetString() 成员对其进行解码。

作为额外的完整性检查,您可以使用 RETR 返回的消息大小,看看它是否与 LIST 返回的匹配。如果它们不匹配,至少我会使用 RETR 返回的内容。

关于c# - 请帮助解决我使用 POP3 协议(protocol)检索电子邮件的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/762553/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com