制作wp7邮箱客户端之socket基础实现

  在上一篇准备工作完成之后,我们对开发邮箱客户端的原理有了基本的认识。那么来看看我们在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的功能……

待续……

posted @ 2012-01-18 13:26  allanxyq  阅读(2544)  评论(6编辑  收藏  举报