zoukankan      html  css  js  c++  java
  • 制作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的功能……

    待续……

  • 相关阅读:
    菜根谭#298
    菜根谭#297
    菜根谭#296
    菜根谭#295
    菜根谭#294
    菜根谭#293
    菜根谭#292
    菜根谭#291
    菜根谭#290
    菜根谭#289
  • 原文地址:https://www.cnblogs.com/allanxyq/p/2325450.html
Copyright © 2011-2022 走看看