C# WiFi多线程收发报文

本文详细介绍了一种网络通信客户端的设计与实现方案,包括客户端与服务器的连接、数据收发流程,以及事件处理机制。文章深入探讨了客户端的构造、连接、发送与接收数据的方法,并实现了异常处理和日志记录功能。

网络通信

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

        public event EventHandler<EventArgCollection.ConnectionEventArgs> OnConnectionChanged;

        public event EventHandler<EventArgCollection.SocketEventArgs> OnSocketEventRaised;

        public event EventHandler<EventArgCollection.SocketErrorEventArgs> OnSocketErrorRaised;

        #region 字段

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

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

        /// <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 NetClient()
        {
            _coder = new Coder(Coder.EncodingMothord.Default);
        }

        /// <summary>
        /// 构造函数,使用一个特定的编码器来初始化
        /// </summary>
        /// <param name="_coder">报文编码器</param>
        public NetClient(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 newClientSocket = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp);

            try
            {

                IPEndPoint iep = new IPEndPoint(IPAddress.Parse(ip), port);
                newClientSocket.BeginConnect(iep, new AsyncCallback(Connected), newClientSocket);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public virtual void Disconnect()
        {

        }


        /// <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>
        /// <param name="dataBytes"></param>
        public virtual void SendBytes(byte[] dataBytes)
        {
            if (dataBytes.Length == 0)
            {
                return;
            }

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

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

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


        #endregion

        #region 受保护方法

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

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

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


        
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值