ClientPeer

2020-05-08  本文已影响0人  高呼吾名
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;

public class ClientPeer {

    public Socket ClientSocket { get; set; }

    public ClientPeer() {
        this.ReceiveArgs = new SocketAsyncEventArgs();
        this.ReceiveArgs.UserToken = this;
        this.ReceiveArgs.SetBuffer(new byte[1024],0,1024);
        this.SendArgs = new SocketAsyncEventArgs();
        this.SendArgs.Completed += SendArgs_Completed;

    }
    #region 辅助方法
    public string GetIP() {
        return ClientSocket.RemoteEndPoint.ToString().Split(':')[0];
    }
    public string GetPort() {
        return ClientSocket.RemoteEndPoint.ToString().Split(':')[1];
    }
    #endregion

    #region 接受数据 

    public delegate void ReceiveCompleted(ClientPeer client,SocketMsg msg);

    //一条消息解析完成的回调
    public ReceiveCompleted receiveCompleted;

    //数据缓存,一旦接收到数据就存到缓存里
    private List<byte> dataCache = new List<byte>();

    //接受的异步套接字请求
    public SocketAsyncEventArgs ReceiveArgs { get; set; }

    //是否正在处理接收的数据
    private bool isReceiveProcess = false;

    private byte[] buffer = new byte[102400];
    public void StartReceiveTask() {
        Task.Run(()=> {
            BeginReceive();
        });
    }

    private void BeginReceive() {
        ClientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallBack, ClientSocket);
    }



    private void ReceiveCallBack(IAsyncResult ar) {
        try {
            int len = ClientSocket.EndReceive(ar);
            if (len > 0) {
                StartReceive(buffer.Take(len).ToArray());
                BeginReceive();
            } else {
                sendDisconnect(this, "客户端主动断开");
            }

        } catch (Exception) {

            sendDisconnect(this, "客户端主动断开");
        }
    }

    /// <summary>
    /// client自身处理数据包
    /// </summary>
    /// <param name="packet"></param>
    public void StartReceive(byte[] packet) {
        try {
            dataCache.AddRange(packet);
            if (isReceiveProcess == false) {
                processReceive();
            }
        } catch (Exception e) {
            Console.WriteLine(TimerManager.GetNowTime() + "-" + e .ToString());
        }
    }

    /// <summary>
    /// 处理接收到的数据
    /// </summary>
    private void processReceive() {
        try {
            isReceiveProcess = true;
            byte[] data = EncodeTool.DecodePacket(ref dataCache);
            if (data == null || data.Length <= 0 ) {
                isReceiveProcess = false;
                return;
            }
            SocketMsg msg = EncodeTool.DecodeMsg(data);

            //回调给上层
            if (receiveCompleted != null) {
                receiveCompleted(this,msg);
            }
            processReceive();
        } catch (Exception e) {
            Console.WriteLine(TimerManager.GetNowTime()+"-"+e.ToString());
        }
    }

    #endregion


    #region 发送数据
    private Queue<byte[]> sendQueue = new Queue<byte[]>();

    private bool isSendProcess = false;

    //用来发送数据的异步socket操作
    private SocketAsyncEventArgs SendArgs;

    public void Send(int opCode,int subCode, object value) {
        try {
            string jsonStr = EncodeTool.EnJsonObj(value);
            SocketMsg msg = new SocketMsg(opCode, subCode, jsonStr);
            Console.WriteLine(EncodeTool.EnJsonObj(msg));
            byte[] data = EncodeTool.EncodeMsg(msg);
            byte[] packet = EncodeTool.EncodePacket(data);
            Send(packet);
        } catch (Exception e) {

            Console.WriteLine(TimerManager.GetNowTime()+"-"+e.ToString());
        }
    }
    public void Send(byte[] packet) {
        try {
            sendQueue.Enqueue(packet);
            if (!isSendProcess) {
                send();
            }
        } catch (Exception e) {

            Console.WriteLine(TimerManager.GetNowTime()+"-"+e.ToString());
        }
    }

    private void send() {
        try {
            isSendProcess = true;
            //如果数据的条数等于0 停止发送
            if (sendQueue.Count <= 0) {
                isSendProcess = false;
                return;
            }
            //取出一条数据
            byte[] packet = sendQueue.Dequeue();
            SendArgs.SetBuffer(packet,0,packet.Length);
            bool result = ClientSocket.SendAsync(SendArgs);
            if (result == false) {
                processSend();
            }

        } catch (Exception e) {

            Console.WriteLine(TimerManager.GetNowTime()+"-"+e.ToString());
        }
    }

    //当数据发送到连接的socket对象时自动调用的事件
    private void SendArgs_Completed(object sender,SocketAsyncEventArgs e) {
        //继续发送
        processSend();
    }

    //发送请求完成时调用  判断发送是否成功
    private void processSend() {
        try {
            if (SendArgs.SocketError != SocketError.Success) {
                //发送错误 客户端断开连接停止发送
                sendDisconnect(this,SendArgs.SocketError.ToString());
            } else {
                send();
            }
        } catch (Exception e) {
            Console.WriteLine(TimerManager.GetNowTime()+"-"+e.ToString());
        }
    }

    #endregion

    #region 断开连接

    //发送的时候 发现断开的回调
    public delegate void SendDisconnect(ClientPeer client, string reason);

    public SendDisconnect sendDisconnect;

    public void Disconnect() {
        try {
            //清空数据
            dataCache.Clear();
            isReceiveProcess = false;
            sendQueue.Clear();
            isSendProcess = false;
            if (ClientSocket == null) {
                return;
            }
            //ClientSocket.Shutdown(SocketShutdown.Both);
            ClientSocket.Close();
            ClientSocket = null;
        } catch (Exception e) {
            Console.WriteLine(TimerManager.GetNowTime()+"-"+e.ToString());
        }
    }

    #endregion
}
上一篇下一篇

猜你喜欢

热点阅读