在上一篇准備工作完成之后,我們對開發郵箱客戶端的原理有了基本的認識。那么來看看我們在wp7上有哪些資源來供我們開發吧,也就是說看看wp7對開發郵箱提供了哪些API支持。wp7沒有像android和。net framework上面的那種封裝好的imap類也沒有mail類,我們要自己做這些工作。
因為開發郵箱最基本的需求是在imap、stmp協議上的通信,他們屬於tcp家族中的一員,原理很簡單就是我對服務器發送一個指令,服務器針對指令做出響應,所以在這過程中需要用到通信的socket類,編碼解碼的encoding類,和多線程的控制,這些在wp7中都有了,好,我們可以開工了。
建一個基類tcpclientBase.cs 用來實現收發消息的基本功能
abstract public class TCPClientBase : IDisposable
{
/// <summary>
/// 端口
/// </summary>
const int IMAP_PORT = 143;
/// <summary>
/// 緩沖區大小
/// </summary>
const int MAX_BUFFER_READ_SIZE = 2048;
/// <summary>
/// 多線程通知超時時間
/// </summary>
const int TIMEOUT_MILLISECONDS = 5000;
/// <summary>
/// socket客戶端
/// </summary>
Socket _socket;
protected static int IMAP_COMMAND_VAL = 0;
static ManualResetEvent _clientDone = new ManualResetEvent(false);
/// <summary>
/// 是否連接
/// </summary>
public Boolean IsConnect
{
get
{
if (_socket != null)
{
return _socket.Connected;
}
else
return false;
}
}
/// <summary>
/// 訪問終端
/// </summary>
EndPoint _dnsEndPoint;
/// <summary>
/// 構造函數
/// </summary>
/// <param name="HostName">主機名</param>
public TCPClientBase(string HostName)
{
Initialization(new DnsEndPoint(HostName, IMAP_PORT));
}
/// <summary>
/// 構造函數
/// </summary>
/// <param name="ipaddress">IP地址</param>
public TCPClientBase(IPAddress ipaddress)
{
Initialization(new IPEndPoint(ipaddress, IMAP_PORT));
}
/// <summary>
/// 實例化連接
/// </summary>
/// <param name="endPorint"></param>
void Initialization(EndPoint endPorint)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_dnsEndPoint = endPorint;
SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs()
{
RemoteEndPoint = _dnsEndPoint,
};
socketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>((o, e) =>
{
_clientDone.Set();
});
_clientDone.Reset();
_socket.ConnectAsync(socketAsyncEventArgs);
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
ResponseReceivedResult result = this.Receive();
}
/// <summary>
/// 發送消息
/// </summary>
/// <param name="data"></param>
/// <param name="onComplete"></param>
protected void Send(string data, Action<ResponseReceivedEventArgs> onComplete)
{
if (_socket == null)
{
throw new Exception("連接已關閉");
}
SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs() { RemoteEndPoint = _dnsEndPoint };
byte[] byteDate = Encoding.UTF8.GetBytes(data);
socketAsyncEventArgs.SetBuffer(byteDate, 0, byteDate.Length);
socketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>((o, e) =>
{
ResponseReceivedEventArgs arg = new ResponseReceivedEventArgs();
arg.isError = e.SocketError == SocketError.Success ? true : false;
arg.response = string.Empty;
if (onComplete != null)
{
postUI(() =>
{
onComplete(arg);
});
}
_clientDone.Set();
});
_clientDone.Reset();
_socket.SendAsync(socketAsyncEventArgs);
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
/// <summary>
/// 拋到UI主線程
/// </summary>
/// <param name="onComplete"></param>
private static void postUI(Action onComplete)
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
{
onComplete();
});
}
/// <summary>
/// 接收
/// </summary>
/// <returns></returns>
protected ResponseReceivedResult Receive()
{
ResponseReceivedResult args = new ResponseReceivedResult();
string response = "Time Out!";
if (_socket == null)
{
throw new Exception("連接已關閉");
}
SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs() { RemoteEndPoint = _dnsEndPoint };
socketArgs.SetBuffer(new byte[MAX_BUFFER_READ_SIZE], 0, MAX_BUFFER_READ_SIZE);
socketArgs.Completed += new EventHandler<SocketAsyncEventArgs>((o, e) =>
{
if (e.SocketError == SocketError.Success)
{
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
args.isError = true;
}
else
args.isError = false;
_clientDone.Set();
});
_clientDone.Reset();
_socket.ReceiveAsync(socketArgs);
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
args.response = response;
return args;
}
protected virtual void Disconnect()
{
if (IsDisposed)
{
throw new ObjectDisposedException("TCPClientBase");
}
if (!IsConnect)
{
throw new InvalidOperationException("TCPClient is not connected");
}
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
_socket.Dispose();
_clientDone.Dispose();
_dnsEndPoint = null;
}
/// <summary>
/// 實現dispose接口
/// </summary>
#region Dispose
private bool IsDisposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
lock (this)
{
if (!this.IsDisposed)
{
if (disposing)
{
#warning 要做異常捕獲
Disconnect();
}
IsDisposed = true;
}
}
}
~TCPClientBase()
{
Dispose(false);
}
#endregion
}
然后繼承TCP類實現imap和smtp的功能……
待續……