当前位置:编程学习 > C#/ASP.NET >>

提供Tcp网络连接服务的客户端类

/// <summary>
 /// 提供Tcp网络连接服务的客户端类
 ///
 /// 版本:  1.0
 /// 替换版本:
 ///
 /// 特征:
 /// 原理:
 /// 1.使用异步Socket通讯与服务器按照一定的通讯格式通讯,请注意与服务器的通
 /// 讯格式一定要一致,否则可能造成服务器程序崩溃,整个问题没有克服,怎么从byte[]
 /// 判断它的编码格式
 /// 2.支持带标记的数据报文格式的识别,以完成大数据报文的传输和适应恶劣的网
 /// 络环境.
 /// 用法:
 /// 注意:
 /// </summary>
 public class TcpCli
 {
  #region 字段

  /// <summary>
  /// 客户端与服务器之间的会话类
  /// </summary>
  private Session _session;

  /// <summary>
  /// 客户端是否已经连接服务器
  /// </summary>
  private bool _isConnected = false;

  /// <summary>
  /// 接收数据缓冲区大小64K
  /// </summary>
  public const int DefaultBufferSize = 64*1024;

  /// <summary>
  /// 报文解析器
  /// </summary>
  private DatagramResolver _resolver;

  /// <summary>
  /// 通讯格式编码解码器
  /// </summary>
  private Coder _coder;

  /// <summary>
  /// 接收数据缓冲区
  /// </summary>
  private byte[] _recvDataBuffer = new byte[DefaultBufferSize];

  #endregion

  #region 事件定义

  //需要订阅事件才能收到事件的通知,如果订阅者退出,必须取消订阅
 
  /// <summary>
  /// 已经连接服务器事件
  /// </summary>
  public event NetEvent ConnectedServer;

  /// <summary>
  /// 接收到数据报文事件
  /// </summary>
  public event NetEvent ReceivedDatagram;

  /// <summary>
  /// 连接断开事件
  /// </summary>
  public event NetEvent DisConnectedServer;
  #endregion

  #region 属性

  /// <summary>
  /// 返回客户端与服务器之间的会话对象
  /// </summary>
  public Session ClientSession
  {
   get
   {
    return _session;
   }
  }

  /// <summary>
  /// 返回客户端与服务器之间的连接状态
  /// </summary>
  public bool IsConnected
  {
   get
   {
    return _isConnected;
   }
  }

  /// <summary>
  /// 数据报文分析器
  /// </summary>
  public DatagramResolver Resovlver
  {
   get
   {
    return _resolver;
   }
   set
   {
    _resolver = value;
   }
  }

  /// <summary>
  /// 编码解码器
  /// </summary>
  public Coder ServerCoder
  {
   get
   {
    return _coder;
   }
  }

  #endregion
 
  #region 公有方法

  /// <summary>
  /// 默认构造函数,使用默认的编码格式
  /// </summary>
  public TcpCli()
  {
   _coder = new Coder( Coder.EncodingMothord.Default );
  }

  /// <summary>
  /// 构造函数,使用一个特定的编码器来初始化
  /// </summary>
  /// <param name="_coder">报文编码器</param>
  public TcpCli( Coder coder )
  {
   _coder = coder;
  }

  /// <summary>
  /// 连接服务器
  /// </summary>
  /// <param name="ip">服务器IP地址</param>
  /// <param name="port">服务器端口</param>
  public virtual void Connect( string ip, int port)
  {
   if(IsConnected)
   {
    //重新连接
    Debug.Assert( _session !=null);

    Close();
   }

   Socket newsock= new Socket(AddressFamily.InterNetwork,
    SocketType.Stream, ProtocolType.Tcp);

   IPEndPoint iep = new IPEndPoint( IPAddress.Parse(ip), port);
   newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);

  }

  /// <summary>
  /// 发送数据报文
  /// </summary>
  /// <param name="datagram"></param>
  public virtual void Send( string datagram)
  {
   if(datagram.Length ==0 )
   {
    return;
   }

   if( !_isConnected )
   {
    throw (new  ApplicationException("没有连接服务器,不能发送数据") );
   }

   //获得报文的编码字节
   byte [] data = _coder.GetEncodingBytes(datagram);

   _session.ClientSocket.BeginSend( data, 0, data.Length, SocketFlags.None,
    new AsyncCallback( SendDataEnd ), _session.ClientSocket);
  }

  /// <summary>
  /// 关闭连接
  /// </summary>
  public virtual void Close()
  {
   if(!_isConnected)
   {
    return;
   }

   _session.Close();

   _session = null;

   _isConnected = false;
  }

  #endregion

  #region 受保护方法

  /// <summary>
  /// 数据发送完成处理函数
  /// </summary>
  /// <param name="iar"></param>
  protected virtual void SendDataEnd(IAsyncResult iar)
  {
   Socket remote = (Socket)iar.AsyncState;
   int sent = remote.EndSend(iar);
   Debug.Assert(sent !=0);

  }

  /// <summary>
  /// 建立Tcp连接后处理过程
  /// </summary>
  /// <param name="iar">异步Socket</param>
  protected virtual void Connected(IAsyncResult iar)
  {
   Socket socket = (Socket)iar.AsyncState;

   socket.EndConnect(iar);

   //创建新的会话
   _session = new Session(socket);
  
   _isConnected = true;

   //触发连接建立事件
   if(ConnectedServer != null)
   {
    ConnectedServer(this, new NetEventArgs(_session));
   }

   //建立连接后应该立即接收数据
   _session.ClientSocket.BeginReceive(_recvDataBuffer, 0,
    DefaultBufferSize, SocketFlags.None,
    new AsyncCallback(RecvData), socket);
  }

  /// <summary>
  /// 数据接收处理函数
  /// </summary>
  /// <param name="iar">异步Socket</param>
  protected virtual void RecvData(IAsyncResult iar)
  {
   Socket remote = (Soc

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,