コード例 #1
0
        /// <summary>
        /// 开启线程发送
        /// 每次发送时调用
        /// </summary>
        private void TaskSend()
        {
            if (!semaphore.WaitOne(100))
            {
                return;
            }
            if (!queue.IsEmpty)
            {
                Task.Factory.StartNew(() =>
                {
                    AsyncUDPSendBuffer buffer = null;
                    do
                    {
                        if (queue.TryDequeue(out buffer))
                        {
                            socket.SendTo(buffer.Buffer, buffer.Offset, buffer.Length, SocketFlags.None, buffer.EndPoint);

                            buffer.FreeDataCache();
                            buffer.Free();
                            if (buffer.Token != null)
                            {
                                AsyncUdpUserToken token = buffer.Token as AsyncUdpUserToken;
                                if (null != token)
                                {
                                    //外部缓存也释放
                                    token.FreeCache();
                                }
                            }
                        }
                    }while (!queue.IsEmpty);
                    semaphore.Release();
                });
            }
        }
コード例 #2
0
 /// <summary>
 /// 接收完成
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="token"></param>
 private void SocketEndPoint_OnDataReceived(object sender, AsyncUdpUserToken token)
 {
     if (OnDataReceived != null)
     {
         OnDataReceived(this, token);
     }
 }
コード例 #3
0
ファイル: UDPPack.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 数据按照分包层大小分包发送
        /// 没有协议
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="host">远端IP</param>
        /// <param name="port">远端端口</param>
        /// <param name="isCache">是否使用分包层缓存分包</param>
        /// <param name="offet">数据区偏移</param>
        /// <param name="len">数据区长度</param>
        public void SendPackage(byte[] data, string host, int port, bool isCache = false, int offet = 0, int len = 0)
        {
            //使用了分包缓存
            int index = 0;
            AsyncUdpUserToken token = null;

            if (len == 0)
            {
                len = data.Length;
            }
            if (token == null)
            {
                token        = new AsyncUdpUserToken();
                token.Data   = data;
                token.Offset = offet;
                token.Length = len;
                token.Remote = new IPEndPoint(IPAddress.Parse(host), port);
            }
            do
            {
                if (isCache)
                {
                    SendPackage(DataPack.PackCacheUDP(token, ref index));
                }
                else
                {
                    Send(DataPack.PackUDP(token, ref index), host, port);
                }
            } while (index < len);
            token.FreeCache();
        }
コード例 #4
0
        private bool isClear          = false;//是否调用了清理

        /// <summary>
        /// 发送的根数据
        /// </summary>
        /// <param name="token"></param>
        public SendQueue(AsyncUdpUserToken token)
        {
            AsyncUdp   = token;
            packageID  = token.DataPackage.packageID;
            resetEvent = new AutoResetEvent(false);
            Check();//创建时说明数据已经发送了
        }
コード例 #5
0
        public void Bind()
        {
            cacheManager.BufferSize = BufferSize;

            cacheManager.Capacity = TotalBufSize * MByte;
            tokenPool.MaxLeftNum  = TokenMaxLeftNum;
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.SendBufferSize    = 64 * 1024;
            socket.ReceiveBufferSize = 64 * 1024;
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
            if (string.IsNullOrEmpty(Host))
            {
                localEndPoint = new IPEndPoint(IPAddress.Any, Port);
            }
            else
            {
                localEndPoint = new IPEndPoint(IPAddress.Parse(Host), Port);
            }
            socket.Bind(localEndPoint);
            receivebuffer     = new byte[BufferSize];
            receiveSocketArgs = new SocketAsyncEventArgs();
            receiveSocketArgs.RemoteEndPoint = localEndPoint;
            receiveSocketArgs.Completed     += IO_Completed;
            receiveSocketArgs.SetBuffer(receivebuffer, 0, receivebuffer.Length);
            AsyncUdpUserToken token = new AsyncUdpUserToken();

            token.Socket           = socket;
            token.IPAddress        = localEndPoint.Address;
            receiveState           = new AsyncSocketUDPState();
            receiveState.Data      = receivebuffer;
            receiveState.Remote    = localEndPoint;
            receiveState.IPAddress = localEndPoint.Address;
            receiveState.Socket    = socket;
        }
コード例 #6
0
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="host"></param>
        /// <param name="port"></param>
        public void SendPackage(byte[] data, string host, int port)
        {
            AsyncUdpUserToken token = new AsyncUdpUserToken();

            token.Data   = data;
            token.Offset = 0;
            token.Length = data.Length;
            token.Remote = new IPEndPoint(IPAddress.Parse(host), port);
            SendPackage(token);
        }
コード例 #7
0
ファイル: UserTokenPool.cs プロジェクト: zyj0021/DBAcessSrv
 /// <summary>
 /// 置回实体
 /// </summary>
 /// <param name="token"></param>
 public void Push(AsyncUdpUserToken token)
 {
     if (removeNum > 0)
     {
         removeNum--;
         return;
     }
     stack.Push(token);
     Free();
 }
コード例 #8
0
ファイル: UDPPack.cs プロジェクト: zyj0021/DBAcessSrv
 private void UDPSocket_OnDataReceived(object sender, AsyncUdpUserToken token)
 {
     if (IsProtolUnPack)
     {
         token.Offset = token.Offset + UDPDataPackage.HeadLen;
     }
     if (OnDataReceived != null)
     {
         OnDataReceived(this, token);
     }
 }
コード例 #9
0
ファイル: UDPPack.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 按照协议分包组包发送
        /// 一定用到分包层缓存
        /// </summary>
        /// <param name="data"></param>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <param name="offet"></param>
        /// <param name="len"></param>
        public void SendProtol(byte[] data, string host, int port, int offet = 0, int len = 0)
        {
            AsyncUdpUserToken token = new AsyncUdpUserToken();

            token.Data   = data;
            token.Offset = offet;
            token.Length = len;
            token.Remote = new IPEndPoint(IPAddress.Parse(host), port);

            SendProtol(token);
        }
コード例 #10
0
 /// <summary>
 /// 接收完成
 /// </summary>
 /// <param name="seq"></param>
 /// <returns></returns>
 public AsyncUdpUserToken GetAsyncUdpUserToken(int seq)
 {
     lastTime = DateTime.Now;
     if (AsyncUdp.ListPack != null)
     {
         if (AsyncUdp.ListPack.Count > seq)
         {
             AsyncUdpUserToken current = AsyncUdp.ListPack[seq];
             return(current);
         }
     }
     return(null);
 }
コード例 #11
0
        private void SocketEndPoint_OnLossData(object sender, object remote, LosPackage[] list)
        {
            AsyncUdpUserToken token    = new AsyncUdpUserToken();
            IPEndPoint        endPoint = remote as IPEndPoint;

            token.Remote = endPoint;
            foreach (LosPackage los in list)
            {
                los.Pack();
                token.Data = los.PData;
                uDPPack.Send(token, 0);
            }
        }
コード例 #12
0
ファイル: UserTokenPool.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 取出实体
        /// </summary>
        /// <returns></returns>
        public AsyncUdpUserToken Pop()
        {
            AsyncUdpUserToken token = null;

            if (!stack.TryPop(out token))
            {
                token           = new AsyncUdpUserToken();
                token.TokenID   = Interlocked.Increment(ref tokenid);
                token.TokenPool = this;
                emptyTime       = DateTime.Now;
            }
            removeNum--;
            return(token);
        }
コード例 #13
0
ファイル: UDPPack.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 数据分包;采用分包层缓存分包
        /// 分包就不可能使用外部缓存
        ///
        /// </summary>
        /// <param name="token"></param>
        public void SendPackage(AsyncUdpUserToken token)
        {
            //使用了分包缓存
            int index = 0;

            if (token.Length == 0)
            {
                token.Length = token.Data.Length;
            }
            do
            {
                AsyncUdpUserToken userToken = DataPack.PackCacheUDP(token, ref index);
                Send(userToken, 2);
            } while (index < token.Length);
            token.FreeCache();
        }
コード例 #14
0
ファイル: DataPack.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 缓存分包
        /// </summary>
        /// <param name="token"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static AsyncUdpUserToken PackCacheUDP(AsyncUdpUserToken token, ref int index)
        {
            if (cacheUDP == null)
            {
                cacheUDP                = new CacheManager();
                cacheUDP.BufferSize     = UdpPackSize;
                cacheUDP.MaxBufferCount = MaxUseBytes / UdpPackSize * 2;
            }
            if (tokenPool == null)
            {
                tokenPool = new UserTokenPool();
            }
            if (token.Length == 0)
            {
                token.Length = token.Data.Length;
            }
            //
            byte[]            buf       = null;
            AsyncUdpUserToken userToken = tokenPool.Pop();

            userToken.Remote     = token.Remote;
            userToken.IPAddress  = token.IPAddress;
            userToken.IsFixCache = false;
            userToken.Socket     = token.Socket;
            if (index + UdpPackSize <= token.Length)
            {
                //分包
                if (!cacheUDP.GetBuffer(out buf))
                {
                    buf = new byte[UdpPackSize];//与
                }
                Array.Copy(token.Data, token.Offset + index, buf, 0, UdpPackSize);
                index              += UdpPackSize;
                userToken.Cache     = cacheUDP;
                userToken.TokenPool = tokenPool;
            }
            else
            {
                int len = token.Length - index;
                buf = new byte[len];
                Array.Copy(token.Data, token.Offset + index, buf, 0, len);
                index += len;
                userToken.TokenPool = tokenPool;
            }
            return(userToken);
        }
コード例 #15
0
ファイル: UDPSocket.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 发送完成处理
        /// </summary>
        /// <param name="e"></param>
        private void ProcessSent(SocketAsyncEventArgs e)
        {
            if (e.UserToken == null)
            {
                //说明是直接发送或者不够缓存时新创建的
                e.SetBuffer(null, 0, 0);
                e.Completed -= IO_Completed;
            }
            else
            {
                //来自外部缓存或者本层缓存
                AsyncUdpUserToken token = e.UserToken as AsyncUdpUserToken;
                if (null != token)
                {
                    //来自外部数据
                    if (token.UserInfo == "outcache")
                    {
                        token.FreeCache();
                        e.SetBuffer(null, 0, 0);
                        e.Completed -= IO_Completed;
                    }
                }


                //else
                //{
                //    //回收缓存;如果发送每次在获取,则要释放
                //    //如果发送时判断分配缓存了,这里就可以不回收
                //    if (IsFixCache)
                //    {
                //        bufferManager.FreeBuffer(e);
                //    }
                //   else
                //    {
                //        bufferManager.GetBuffer(e);
                //    }

                //}
            }
            e.UserToken = null;
            pool.Push(e);
        }
コード例 #16
0
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="token"></param>
        public void SendPackage(AsyncUdpUserToken token)
        {
            if (uDPPack == null)
            {
                Bind();
            }
            //使用了分包缓存
            token.ListPack = new List <AsyncUdpUserToken>();
            //
            uDPPack.SendProtol(token);
            //
            if (dicSendQueue == null)
            {
                dicSendQueue = new ConcurrentDictionary <long, SendQueue>();
            }
            SendQueue sendList = new SendQueue(token);

            dicSendQueue[token.DataPackage.packageID] = sendList;
            sendList.PushLossReset += SendList_PushLossReset;
        }
コード例 #17
0
 /// <summary>
 /// 接收完成
 /// </summary>
 /// <param name="seq"></param>
 public void Add(int seq)
 {
     lastTime = DateTime.Now;
     if (AsyncUdp.ListPack != null)
     {
         if (AsyncUdp.ListPack.Count > seq)
         {
             try
             {
                 //ListPack没有同步
                 AsyncUdpUserToken current = AsyncUdp.ListPack[seq];
                 packageID = current.DataPackage.packageID;
                 current.FreeCache();
                 AsyncUdp.ListPack[seq] = null;
             }
             catch (Exception ex)
             {
             }
         }
     }
 }
コード例 #18
0
ファイル: UDPPack.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 按照协议分包组包发送
        /// </summary>
        /// <param name="token"></param>
        public void SendProtol(AsyncUdpUserToken token)
        {
            //使用了分包缓存
            int index = 0;

            if (token.Length == 0)
            {
                token.Length = token.Data.Length;
            }
            do
            {
                AsyncUdpUserToken userToken = DataPack.PackCacheUDPHead(token, ref index);
                userToken.Remote = token.Remote;
                Send(userToken, 2);
                if (token.ListPack != null)
                {
                    token.ListPack.Add(userToken);
                }
            } while (index < token.Length);
            token.FreeCache();
        }
コード例 #19
0
        /// <summary>
        /// 处理接收的数据
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="Offset"></param>
        /// <param name="len"></param>
        /// <param name="isCache"></param>
        private void DoEventRecvice(byte[] buf, EndPoint remote, int Offset = 0, int len = 0, bool isCache = false)
        {
            AsyncUdpUserToken token = tokenPool.Pop();

            token.Data       = buf;
            token.Offset     = Offset;
            token.Length     = len;
            token.IsFixCache = IsFixCache;
            token.Remote     = remote;
            token.Socket     = socket;
            if (isCache)
            {
                token.Cache = cacheManager;
            }
            if (OnDataReceived != null)
            {
                Task.Factory.StartNew(() =>
                {
                    OnDataReceived(this, token);
                });
            }
        }
コード例 #20
0
ファイル: RecviceData.cs プロジェクト: zyj0021/DBAcessSrv
        private void Pool_OnReviceData(object sender, long id, byte[] data, RecviceState state)
        {
            //一组接收完成
            if (dicSucess.ContainsKey(id))
            {
                return;
            }
            dicSucess[id] = DateTime.Now;
            RecvicePool pool = null;

            dicPool.TryRemove(id, out pool);
            if (OnDataReceived != null)
            {
                AsyncUdpUserToken token = new AsyncUdpUserToken();
                token.Data   = data;
                token.Remote = remote;
                token.Length = data.Length;
                Task.Factory.StartNew(() =>
                {
                    OnDataReceived(this, token);
                });
                RecvicePool recvice = sender as RecvicePool;
                if (recvice != null)
                {
                    recvice.Clear();
                }
                recvice.OnLossData   -= Pool_OnLossData;
                recvice.OnReviceData -= Pool_OnReviceData;
                //完成发送一次
                LosPackage package = new LosPackage();
                package.packageType = 3;
                package.packageID   = id;
                Pool_OnLossData(this, remote, new LosPackage[] { package });

                Console.WriteLine("sucess:" + id);
            }
        }
コード例 #21
0
ファイル: SocketEndPoint.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="token"></param>
        public void Add(AsyncUdpUserToken token)
        {
            IPEndPoint endPoint = token.Remote as IPEndPoint;

            if (null != endPoint)
            {
                string key = endPoint.Address.ToString() + endPoint.Port;
                dicRecvice[key] = DateTime.Now;
                RecviceData    data    = null;
                UDPDataPackage package = new UDPDataPackage();
                package.UnPack(token.Data, token.Offset, token.Length);
                if (dicPool.TryGetValue(key, out data))
                {
                    data.Add(package);
                }
                else
                {
                    lock (lock_obj)
                    {
                        //阻塞创建
                        if (!dicPool.TryGetValue(key, out data))
                        {
                            data                 = new RecviceData();
                            dicPool[key]         = data;
                            data.remote          = endPoint;
                            data.OnDataReceived += Data_OnDataReceived;
                            data.OnLossData     += Data_OnLossData;
                            data.Add(package);
                        }
                        else
                        {
                            data.Add(package);
                        }
                    }
                }
            }
        }
コード例 #22
0
ファイル: DataPack.cs プロジェクト: zyj0021/DBAcessSrv
 /// <summary>
 /// 直接创建byte[]分包
 /// </summary>
 /// <param name="token"></param>
 /// <param name="index"></param>
 /// <returns></returns>
 public static byte[] PackUDP(AsyncUdpUserToken token, ref int index)
 {
     if (token.Length == 0)
     {
         token.Length = token.Data.Length;
     }
     //
     byte[] buf = null;
     if (index + UdpPackSize <= token.Length)
     {
         //分包
         buf = new byte[UdpPackSize];
         Array.Copy(token.Data, token.Offset + index, buf, 0, UdpPackSize);
         index += UdpPackSize;
     }
     else
     {
         int len = token.Length - index;
         buf = new byte[len];
         Array.Copy(token.Data, token.Offset + index, buf, 0, len);
         index += len;
     }
     return(buf);
 }
コード例 #23
0
ファイル: UDPSocket.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="token"></param>
        /// <param name="isCache"></param>
        public void SendPackage(AsyncUdpUserToken token, int isCache = 0)
        {
            /*
             * 说明,通信层的缓存不回收,其余的数据均回收
             * 0.socketArgs.UserToken=null,直接设置buffer=null(标记UserToken=null)
             * 1.本层缓存,不回收buffer;(不做任何处理,每次有多个)
             * 2.外部缓存,回收直接设置buffer=null,同时回收使用缓存(每次只会有一个,直接回收)
             */
            if (0 == isCache)
            {
                Send(token.Data, token.Remote, token.Offset, token.Length);
            }
            else if (1 == isCache)
            {
                //使用通信缓存分组发送;
                //只有这个分支会用到通信缓存
                int index = token.Offset;
                do
                {
                    SocketAsyncEventArgs socketArgs = pool.Pop();
                    socketArgs.RemoteEndPoint = token.Remote;
                    socketArgs.UserToken      = token;
                    token.Socket   = socket;
                    token.UserInfo = "udpcache";
                    if (socketArgs.Buffer == null)
                    {
                        //没有分配缓存时才分配
                        if (IsFixCache)
                        {
                            bufferManager.SetBuffer(socketArgs);
                        }
                        else
                        {
                            bufferManager.GetBuffer(socketArgs);
                        }
                        socketArgs.Completed += IO_Completed;
                    }
                    if (token.Length == 0)
                    {
                        token.Length = token.Data.Length;
                    }
                    //拷贝数据到本缓存,
                    if (socketArgs.Count + index >= token.Length)
                    {
                        Array.Copy(token.Data, token.Offset + index, socketArgs.Buffer, socketArgs.Offset, socketArgs.Count);
                        index += socketArgs.Count;
                    }
                    else
                    {
                        //不够缓存发送了
                        byte[] tmp = new byte[token.Length - index];
                        Array.Copy(token.Data, token.Offset + index, tmp, 0, tmp.Length);
                        index += tmp.Length;

                        //先释放
                        if (socketArgs.Buffer != null)
                        {
                            //说明来自缓存
                            if (IsFixCache)
                            {
                                bufferManager.FreeBuffer(socketArgs);
                            }
                            else
                            {
                                bufferManager.FreePoolBuffer(socketArgs);
                            }
                        }
                        else
                        {
                            //说明来自创建
                            socketArgs.SetBuffer(null, 0, 0);
                        }
                        socketArgs.SetBuffer(tmp, 0, tmp.Length);
                        socketArgs.UserToken = null;
                    }
                    //

                    if (socketArgs.RemoteEndPoint != null)
                    {
                        if (!socket.SendToAsync(socketArgs))
                        {
                            ProcessSent(socketArgs);
                        }
                    }
                } while (index < token.Length);
                token.FreeCache();//用完外部的了;
            }
            else if (2 == isCache)
            {
                SocketAsyncEventArgs socketArgs = pool.Pop();
                socketArgs.RemoteEndPoint = token.Remote;
                token.UserInfo            = "outcache";
                if (token.Length == 0)
                {
                    token.Length = token.Data.Length;
                }
                if (socketArgs.Buffer != null)
                {
                    if (IsFixCache)
                    {
                        bufferManager.FreeBuffer(socketArgs);
                    }
                    else
                    {
                        bufferManager.FreePoolBuffer(socketArgs);
                    }

                    socketArgs.SetBuffer(null, 0, 0);
                }
                else
                {
                    socketArgs.Completed += IO_Completed;
                }
                //持续使用外部缓存发送,发送后要释放
                socketArgs.UserToken = token;
                socketArgs.SetBuffer(token.Data, token.Offset, token.Length);
                if (socketArgs.RemoteEndPoint != null)
                {
                    if (!socket.SendToAsync(socketArgs))
                    {
                        ProcessSent(socketArgs);
                    }
                }
            }
            else
            {
                Console.WriteLine("isCache参数不正确");
            }
        }
コード例 #24
0
        /// <summary>
        /// 接收底层的数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="token"></param>
        private void UDPSocket_OnDataReceived(object sender, AsyncUdpUserToken token)
        {
            Console.WriteLine("接收数据个数:" + token.Length);
            switch (token.Data[token.Offset])
            {
            case 0:
            {
                //数据
                socketEndPoint.Add(token);
                if (isValidatePoint)
                {
                    isValidatePoint = false;
                    EndPointValidate();
                }
            }
            break;

            case 1:
            {
                //接收完成序列
                Console.WriteLine("接收小包完成返回");
                SendQueue  sendQueue = null;
                LosPackage rsp       = new LosPackage(token.Data);
                if (dicSendQueue.TryGetValue(rsp.packageID, out sendQueue))
                {
                    sendQueue.Add(rsp.packageSeq);
                }
            }
            break;

            case 2:
            {
                //丢失序列
                Console.WriteLine("接收丢失请求");
                SendQueue  sendQueue = null;
                LosPackage rsp       = new LosPackage(token.Data);
                if (dicSendQueue.TryGetValue(rsp.packageID, out sendQueue))
                {
                    AsyncUdpUserToken resend = sendQueue.GetAsyncUdpUserToken(rsp.packageSeq);
                    if (resend != null)
                    {
                        uDPPack.Send(resend, 0);
                    }
                }
            }
            break;

            case 3:
            {
                //完成接收

                SendQueue  sendQueue = null;
                LosPackage rsp       = new LosPackage(token.Data);
                if (dicSendQueue.TryRemove(rsp.packageID, out sendQueue))
                {
                    sendQueue.Clear();
                }
                Console.WriteLine("接收完成返回:" + rsp.packageID);
            }
            break;
            }
        }
コード例 #25
0
ファイル: UDPPack.cs プロジェクト: zyj0021/DBAcessSrv
 /// <summary>
 /// 发送数据
 /// isCache:
 /// 0直接使用数据区发送(没有缓存)
 /// 1拷贝通信层缓存发送(分割缓存大小发送)
 /// 2外部缓存发送,发送完成释放
 /// </summary>
 /// <param name="token">数据封</param>
 /// <param name="isCache">
 /// 0直接使用数据区发送(没有缓存)
 /// 1拷贝发送层缓存发送(分割缓存大小发送)
 /// 2外部缓存发送,发送完成释放
 ///
 /// </param>
 public void Send(AsyncUdpUserToken token, int isCache)
 {
     uDPSocket.SendPackage(token, isCache);
 }
コード例 #26
0
ファイル: DataPack.cs プロジェクト: zyj0021/DBAcessSrv
        /// <summary>
        /// 缓存分包;如果不到缓存长度就创建byte[],通过isUse
        /// </summary>
        /// <param name="token"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static AsyncUdpUserToken PackCacheUDPHead(AsyncUdpUserToken token, ref int index)
        {
            if (cacheUDP == null)
            {
                cacheUDP                = new CacheManager();
                cacheUDP.BufferSize     = UdpPackSize;
                cacheUDP.MaxBufferCount = MaxUseBytes / UdpPackSize * 2;
            }
            if (tokenPool == null)
            {
                tokenPool = new UserTokenPool();
            }
            if (token.Length == 0)
            {
                token.Length = token.Data.Length;
            }
            //
            byte[]            buf       = null;
            AsyncUdpUserToken userToken = tokenPool.Pop();

            userToken.Remote     = token.Remote;
            userToken.IPAddress  = token.IPAddress;
            userToken.IsFixCache = false;
            userToken.Socket     = token.Socket;
            if (token.DataPackage == null)
            {
                token.DataPackage            = new UDPDataPackage();
                token.DataPackage.packageID  = Interlocked.Increment(ref dataPackageid);
                token.DataPackage.packageSeq = -1;
                token.DataPackage.packageSum = token.Length;
                token.DataPackage.data       = token.Data;
                token.DataPackage.DataLen    = token.Length;
                token.DataPackage.Offset     = token.Offset;
                token.PackageNum             = token.Length / UdpPackSize + 1;
                token.DataPackage.PackageNum = token.PackageNum;
            }
            if (index + UdpPackSize <= token.Length)
            {
                //分包
                if (!cacheUDP.GetBuffer(out buf))
                {
                    buf = new byte[UdpPackSize];     //与
                }
                token.Offset = token.Offset + index; //移动偏移量
                token.DataPackage.Pack(buf, 0, UdpPackSize);
                userToken.Data   = token.DataPackage.data;
                userToken.Length = UdpPackSize;
                // Array.Copy(token.Data, token.Offset + index, buf, 0, UdpPackSize);
                index              += UdpPackSize;
                userToken.Cache     = cacheUDP;
                userToken.TokenPool = tokenPool;
            }
            else
            {
                int len = token.Length - index;
                buf          = new byte[len + UDPDataPackage.HeadLen]; //头
                token.Offset = token.Offset + index;                   //移动偏移量
                token.DataPackage.Pack(buf, 0, buf.Length);            //这样做恰好合适,内部分包不判断
                //Array.Copy(token.Data, token.Offset + index, buf, 0, len);
                userToken.Data      = buf;
                userToken.Length    = buf.Length;
                index              += len;
                userToken.TokenPool = tokenPool;
            }
            return(userToken);
        }
コード例 #27
0
        private void Recieve(IAsyncResult ar)
        {
            AsyncSocketUDPState so = ar.AsyncState as AsyncSocketUDPState;
            int len = -1;

            try
            {
                len = socket.EndReceiveFrom(ar, ref so.Remote);
                //
                byte[] buf   = null;
                bool   r     = false;
                int    index = 0;
                if (IsFixCache)
                {
                    if (cacheManager.SetBuffer(out buf, out index))
                    {
                        r = true;
                    }
                }
                else
                {
                    if (cacheManager.GetBuffer(out buf))
                    {
                        r = true;
                    }
                }
                //
                if (!r)
                {
                    buf = new byte[len];
                }
                //
                Array.Copy(receiveState.Data, 0, buf, index, len);

                if (EnableHeart)
                {
                    //
                    AsyncUdpUserToken cur    = null;
                    IPEndPoint        remote = so.Remote as IPEndPoint;
                    string            id     = remote.ToString() + remote.Port;
                    if (dicToken.TryGetValue(id, out cur))
                    {
                        cur.DataTime = DateTime.Now;
                    }
                    else
                    {
                        cur           = new AsyncUdpUserToken();
                        cur.IPAddress = localEndPoint.Address;
                        cur.Socket    = socket;
                        cur.Remote    = so.Remote;
                        dicToken[id]  = cur;
                    }

                    bool rCpm = true;
                    if (len == HeartBytes.Length)
                    {
                        for (int i = 0; i < len; i++)
                        {
                            if (buf[i + index] != so.Data[i + so.OffSet])
                            {
                                rCpm = false;
                                break;
                            }
                        }
                    }
                    if (rCpm)
                    {
                        //是心跳包
                        Recvice();
                        return;
                    }
                }
                //不要进行耗时操作
                DoEventRecvice(buf, so.Remote, index, len, r);
            }
            catch (Exception)
            {
                //TODO 处理异常
            }
            finally
            {
                Recvice();
            }
        }
コード例 #28
0
        /// <summary>
        /// 接收完成处理
        /// </summary>
        /// <param name="e"></param>
        private void ProcessReceived(SocketAsyncEventArgs e)
        {
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                byte[] buf   = null;
                bool   r     = false;
                int    index = 0;
                int    len   = e.BytesTransferred;
                if (IsFixCache)
                {
                    if (cacheManager.SetBuffer(out buf, out index))
                    {
                        r = true;
                    }
                }
                else
                {
                    if (cacheManager.GetBuffer(out buf))
                    {
                        r = true;
                    }
                }
                //
                if (!r)
                {
                    buf = new byte[len];
                }
                //
                Array.Copy(e.Buffer, e.Offset, buf, index, len);

                if (EnableHeart)
                {
                    //
                    AsyncUdpUserToken cur    = null;
                    IPEndPoint        remote = e.RemoteEndPoint as IPEndPoint;
                    string            id     = remote.ToString() + remote.Port;
                    if (dicToken.TryGetValue(id, out cur))
                    {
                        cur.DataTime = DateTime.Now;
                    }
                    else
                    {
                        cur           = new AsyncUdpUserToken();
                        cur.IPAddress = localEndPoint.Address;
                        cur.Socket    = socket;
                        cur.Remote    = e.RemoteEndPoint;
                        dicToken[id]  = cur;
                    }

                    bool rCpm = true;
                    if (len == HeartBytes.Length)
                    {
                        for (int i = 0; i < len; i++)
                        {
                            if (buf[i + index] != e.Buffer[i + e.Offset])
                            {
                                rCpm = false;
                                break;
                            }
                        }
                    }
                    if (rCpm)
                    {
                        //是心跳包
                        StartReceive();
                        return;
                    }
                }
                //不要进行耗时操作
                DoEventRecvice(buf, e.RemoteEndPoint, index, len, r);
            }
            StartReceive();
        }
コード例 #29
0
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="token"></param>
        /// <param name="isCache"></param>
        public void SendPackage(AsyncUdpUserToken token, int isCache = 0)
        {
            /*
             * 说明,通信层的缓存不回收,其余的数据均回收
             * 0.socketArgs.UserToken=null,直接设置buffer=null(标记UserToken=null)
             * 1.本层缓存,不回收buffer;(不做任何处理,每次有多个)
             * 2.外部缓存,回收直接设置buffer=null,同时回收使用缓存(每次只会有一个,直接回收)
             */
            if (0 == isCache)
            {
                Send(token.Data, token.Remote, token.Offset, token.Length);
            }
            else if (1 == isCache)
            {
                //使用通信缓存分组发送;
                //只有这个分支会用到通信缓存
                int    index      = token.Offset;
                byte[] sendBuffer = null;
                int    Offset     = 0;
                int    len        = 0;
                do
                {
                    token.Socket   = socket;
                    token.UserInfo = "udpcache";

                    if (token.Length == 0)
                    {
                        token.Length = token.Data.Length;
                    }
                    //拷贝数据到本缓存
                    AsyncUDPSendBuffer buffer = uDPSendPool.Pop();
                    buffer.EndPoint = token.Remote;
                    if (IsFixCache)
                    {
                        cacheManager.SetBuffer(out sendBuffer, out Offset);
                    }
                    else
                    {
                        cacheManager.GetBuffer(out sendBuffer);
                    }
                    if (cacheManager.BufferSize + index >= token.Length)
                    {
                        Array.Copy(token.Data, token.Offset + index, sendBuffer, Offset, cacheManager.BufferSize);
                        index += cacheManager.BufferSize;
                        len    = cacheManager.BufferSize;
                        //
                        buffer.Offset      = Offset;
                        buffer.Length      = len;
                        buffer.BufferCache = cacheManager;
                        buffer.IsFixCache  = IsFixCache;
                    }
                    else
                    {
                        //不够缓存发送了
                        byte[] tmp = new byte[token.Length - index];
                        Array.Copy(token.Data, token.Offset + index, tmp, 0, tmp.Length);
                        index        += tmp.Length;
                        len           = tmp.Length;
                        buffer.Length = len;
                        buffer.Offset = 0;
                        buffer.Buffer = tmp;
                    }
                    //
                    //socket.SendTo(sendBuffer, Offset, len,SocketFlags.None,token.Remote);

                    queue.Enqueue(buffer);
                } while (index < token.Length);
                token.FreeCache();//用完外部的了;
            }
            else if (2 == isCache)
            {
                token.UserInfo = "outcache";
                if (token.Length == 0)
                {
                    token.Length = token.Data.Length;
                }

                AsyncUDPSendBuffer buffer = uDPSendPool.Pop();
                buffer.Buffer   = token.Data;
                buffer.Offset   = token.Offset;
                buffer.Length   = token.Length;
                buffer.EndPoint = token.Remote;
                buffer.Token    = token;//外部缓存发送完成释放
                queue.Enqueue(buffer);
                //持续使用外部缓存发送,发送后要释放
            }
            else
            {
                Console.WriteLine("isCache参数不正确");
            }
            TaskSend();
        }