Beispiel #1
0
        private void DoEventClient(byte[] data)
        {
            if (ReceiveClientData != null)
            {
                Task.Factory.StartNew(() =>
                {
                    AsyncTcpUserToken token = new AsyncTcpUserToken();
                    token.Remote            = asyncUser.Remote;
                    token.IPAddress         = asyncUser.IPAddress;

                    ReceiveClientData(token, data);
                });
            }
            else
            {
                AsyncTcpUserToken token = null;
                if (queue.Count > 1000)
                {
                    queue.TryTake(out token);
                }
                token           = new AsyncTcpUserToken();
                token.Remote    = asyncUser.Remote;
                token.IPAddress = asyncUser.IPAddress;
                token.Data      = data;
                queue.TryAdd(token);
            }
        }
Beispiel #2
0
        /// <summary>
        /// 初始化
        /// </summary>

        private void Init()
        {
            if (!IsFixCacheSize)
            {
                m_bufferManager.MaxBufferCount = totalBufSize * 1024 * 1024 * 1024;//可以使用最多缓存
            }
            m_clients = new List <AsyncTcpUserToken>();

            SocketAsyncEventArgs readWriteEventArg;

            for (int i = 0; i < m_maxConnectNum; i++)
            {
                readWriteEventArg            = new SocketAsyncEventArgs();
                readWriteEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                AsyncTcpUserToken userToken = new AsyncTcpUserToken();
                userToken.Server            = this;
                readWriteEventArg.UserToken = userToken;

                // assign a byte buffer from the buffer pool to the SocketAsyncEventArg object
                if (IsFixCacheSize)
                {
                    m_bufferManager.SetBuffer(readWriteEventArg);
                }
                else
                {
                    m_bufferManager.GetBuffer(readWriteEventArg);
                }
                // add SocketAsyncEventArg to the pool
                m_pool.Push(readWriteEventArg);
            }
        }
Beispiel #3
0
        /// <summary>
        /// 关闭客户端通信
        /// </summary>
        /// <param name="e"></param>
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncTcpUserToken token = e.UserToken as AsyncTcpUserToken;

            lock (m_clients) { m_clients.Remove(token); }
            //如果有事件,则调用事件,发送客户端数量变化通知
            if (ClientNumberChange != null)
            {
                ClientNumberChange(-1, token);
            }
            try
            {
                token.Socket.Shutdown(SocketShutdown.Send);
            }
            catch (Exception) { }
            token.Socket.Close();
            Interlocked.Decrement(ref m_clientCount);
            if (token != null && !string.IsNullOrEmpty(token.UserInfo))
            {
                CacheEntity entity = null;
                if (dic_Entity.TryRemove(token.UserInfo, out entity))
                {
                    //客户端发送使用的缓存要释放
                    entity.Dispose();
                }
                e.UserToken = null;
                e.SetBuffer(null, 0, 0);
                e.Dispose();//新建的,必须释放,不是来自缓存
                return;
            }
            //接收的一定是缓存的
            e.UserToken = new AsyncTcpUserToken();
            m_pool.Push(e);
        }
Beispiel #4
0
 /// <summary>
 /// 关闭客户端,此时任然在接收数据
 /// 所以CloseClientSocket会被调用
 /// </summary>
 /// <param name="token"></param>
 public void CloseClient(AsyncTcpUserToken token)
 {
     try
     {
         token.Socket.Shutdown(SocketShutdown.Both);
     }
     catch (Exception) { }
 }
Beispiel #5
0
 /// <summary>
 /// 处理发送完成后的信息
 /// </summary>
 /// <param name="e"></param>
 private void ProcessSend(SocketAsyncEventArgs e)
 {
     //TCP这里不好判断,缓存全部回收
     if (e.SocketError == SocketError.Success)
     {
         // done echoing data back to the client
         //AsyncUserToken token = (AsyncUserToken)e.UserToken;
         // read the next block of data send from the client
         //bool willRaiseEvent = token.Socket.ReceiveAsync(e);
         //if (!willRaiseEvent)
         //{
         //    ProcessReceive(e);
         //}
         //发送完成回收
         AsyncTcpUserToken token = e.UserToken as AsyncTcpUserToken;
         if (token != null && !string.IsNullOrEmpty(token.UserInfo))
         {
             CacheEntity entity = null;
             if (dic_Entity.TryRemove(token.UserInfo, out entity))
             {
                 //客户端发送使用的缓存要释放
                 entity.Dispose();
             }
             e.UserToken = null;
             e.SetBuffer(null, 0, 0);
             e.Dispose();//新建的,必须释放,不是来自缓存
             return;
         }
         if (e.Count < m_bufferManager.BufferSize)
         {
             //直接释放内存,不是来自缓存
             e.SetBuffer(null, 0, 0);
             e.UserToken = null;
             m_pool.Push(e);
         }
         else
         {
             //缓存回收,发送的需要回收,接收一定循环,发送不是
             if (IsFixCacheSize)
             {
                 m_bufferManager.FreeBuffer(e);
             }
             else
             {
                 m_bufferManager.FreePoolBuffer(e);
             }
             m_pool.Push(e);
         }
     }
     else
     {
         CloseClientSocket(e);
     }
 }
Beispiel #6
0
        /// <summary>
        /// 处理接收
        /// </summary>
        /// <param name="readEventArgs"></param>
        private void ProcessReceive(SocketAsyncEventArgs readEventArgs)
        {
            try
            {
                // check if the remote host closed the connection
                AsyncTcpUserToken token = (AsyncTcpUserToken)readEventArgs.UserToken;
                if (readEventArgs.BytesTransferred > 0 && readEventArgs.SocketError == SocketError.Success)
                {
                    //读取数据;这里也可以考虑建立缓存池获取
                    byte[] data = new byte[readEventArgs.BytesTransferred];
                    Array.Copy(readEventArgs.Buffer, readEventArgs.Offset, data, 0, readEventArgs.BytesTransferred);
                    //lock (token.Buffer)
                    //{
                    //    token.Buffer.AddRange(data);
                    //}

                    //考虑道客户端数据大小,所以接收到一个缓存大小数据
                    //交给后端处理;socket作为基础操作,只管接收
                    if (EnableHeart && data.Length == HeartClient.Length)
                    {
                        if (Enumerable.SequenceEqual(data, HeartClient))
                        {
                            //收到心跳
                            Console.WriteLine("收到客户端心跳");
                            token.Socket.Send(HeartServer);
                            token.DataTime = DateTime.Now;
                            if (!token.Socket.ReceiveAsync(readEventArgs))
                            {
                                this.ProcessReceive(readEventArgs);
                            }
                            return;
                        }
                    }
                    if (ReceiveClientData != null)
                    {
                        ReceiveClientData(token, data);
                    }
                    //继续接收下一次客户端发送的数据
                    //也可能是客户端发送过大,一个buffer接收不了
                    if (!token.Socket.ReceiveAsync(readEventArgs))
                    {
                        this.ProcessReceive(readEventArgs);
                    }
                }
                else
                {
                    CloseClientSocket(readEventArgs);
                }
            }
            catch (Exception xe)
            {
                //RuncomLib.Log.LogUtils.Info(xe.Message + "\r\n" + xe.StackTrace);
            }
        }
Beispiel #7
0
        /// <summary>
        /// 处理连接
        /// </summary>
        /// <param name="acceptEventArg"></param>
        private void ProcessAccept(SocketAsyncEventArgs acceptEventArg)
        {
            try
            {
                Interlocked.Increment(ref m_clientCount);
                SocketAsyncEventArgs readEventArgs = m_pool.Pop();
                AsyncTcpUserToken    userToken     = (AsyncTcpUserToken)readEventArgs.UserToken;
                if (userToken == null)
                {
                    //说明是新的,已经使用的读写还没有返回
                    userToken = new AsyncTcpUserToken();
                    readEventArgs.UserToken  = userToken;
                    readEventArgs.Completed += IO_Completed;
                    userToken.Server         = this;
                    if (IsFixCacheSize) //分配缓存
                    {
                        m_bufferManager.SetBuffer(readEventArgs);
                    }
                    else
                    {
                        m_bufferManager.GetBuffer(readEventArgs);
                    }
                }
                userToken.Socket      = acceptEventArg.AcceptSocket;
                userToken.ConnectTime = DateTime.Now;
                userToken.Remote      = acceptEventArg.AcceptSocket.RemoteEndPoint;
                userToken.IPAddress   = ((IPEndPoint)(acceptEventArg.AcceptSocket.RemoteEndPoint)).Address;

                lock (m_clients) { m_clients.Add(userToken); }

                if (ClientNumberChange != null)
                {
                    //防止同步,不返回,无法绑定数据接收
                    Task.Factory.StartNew(() =>
                    {
                        ClientNumberChange(1, userToken);
                    });
                }
                //获取到连接后立即准备接收数据;绑定接收事件
                if (!acceptEventArg.AcceptSocket.ReceiveAsync(readEventArgs))
                {
                    ProcessReceive(readEventArgs);
                }
            }
            catch (Exception ex)
            {
                //RuncomLib.Log.LogUtils.Info(me.Message + "\r\n" + me.StackTrace);
            }
            if (acceptEventArg.SocketError == SocketError.OperationAborted)
            {
                return;
            }
            StartAccept(acceptEventArg);
        }
Beispiel #8
0
 private void Server_ReceiveClientData(AsyncTcpUserToken token, byte[] buff)
 {
     if (token.TokenID == 0)
     {
         token.TokenID             = Interlocked.Increment(ref clientID);
         token.DataTime            = DateTime.Now;
         dic_Client[token.TokenID] = token;
     }
     if (ReceiveClientData != null)
     {
         ReceiveClientData(token, buff);
     }
 }
Beispiel #9
0
 /// <summary>
 /// 这里不会分包,交给底层
 /// 无法判断是缓存
 /// </summary>
 /// <param name="token"></param>
 /// <param name="message"></param>
 /// <param name="offset"></param>
 /// <param name="len"></param>
 /// <param name="isCache"></param>
 public void SendPackage(AsyncTcpUserToken token, byte[] message, int offset, int len, int isCache = 0)
 {
     if (len == 0)
     {
         SendMessage(token, message);
     }
     else
     {
         byte[] tmp = new byte[len];
         Array.Copy(message, offset, tmp, 0, len);
         SendMessage(token, tmp);
     }
 }
Beispiel #10
0
 private void Client_ReceiveClientData(AsyncTcpUserToken token, byte[] buff)
 {
     asyncUser = token;
     //收集数据
     lock (lst)
     {
         if (isPack)
         {
             lst.AddRange(buff);
             if (currentSize < 0 && lst.Count > 4)
             {
                 currentSize = BitConverter.ToInt32(lst.GetRange(0, 4).ToArray(), 0);
                 head        = 4;
             }
             if (lst.Count > currentSize)
             {
                 //说明数据收集完成
                 byte[] tmp = new byte[currentSize];
                 lst.CopyTo(head, tmp, 0, tmp.Length);   //去除头
                 DoEventClient(tmp);
                 lst.RemoveRange(0, currentSize + head); //包括头
                 if (lst.Count > 4)
                 {
                     currentSize = BitConverter.ToInt32(lst.GetRange(0, 4).ToArray(), 0);
                     head        = 4;
                 }
                 else
                 {
                     currentSize = -1;
                 }
             }
             else if (lst.Count > maxSize)
             {
                 //byte[] tmp= lst.ToArray();
                 //DoEventClient(tmp);
                 //lst.Clear();
                 //currentSize -= lst.Count;
                 byte[] tmp = new byte[maxSize];
                 lst.CopyTo(head, tmp, 0, tmp.Length);//去除头
                 DoEventClient(tmp);
                 currentSize = currentSize - (maxSize + head);
                 head        = 0;
             }
         }
         else
         {
             DoEventClient(buff);
         }
     }
 }
Beispiel #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="token"></param>
        /// <param name="message"></param>
        /// <param name="offset"></param>
        /// <param name="len"></param>
        /// <param name="isCache"></param>
        public void SendPackage(AsyncTcpUserToken token, byte[] message, int offset, int len, int isCache = -1)
        {
            int index = 0;

            byte[]      tmp    = null;
            CacheEntity entity = null;

            switch (isCache)
            {
            case -1:
                server.SendPackage(token, message, offset, len);
                break;

            case 0:
            {
                do
                {
                    tmp = DataPack.PackTCP(message, ref index);
                    server.SendMessage(token, message);
                } while (tmp != null && index < message.Length);
            }
            break;

            case 1:
            {
                do
                {
                    entity = DataPack.PackEntityTCP(message, ref index);
                    server.SendData(token, entity);
                } while (entity != null && index < message.Length);
            }
            break;

            case 2:
            {
                do
                {
                    entity = DataPack.PackEntityTCP(message, ref index);
                    server.SendData(token, entity, "srv");
                } while (entity != null && index < message.Length);
            }
            break;
            }
        }
Beispiel #12
0
 /// <summary>
 /// 处理数据
 /// </summary>
 /// <param name="buff"></param>
 private void DoReceiveEvent(byte[] buff)
 {
     if (ReceiveClientData != null)
     {
         Task.Factory.StartNew(() =>
         {
             AsyncTcpUserToken token = new AsyncTcpUserToken();
             if (string.IsNullOrEmpty(LocalHost))
             {
                 IPEndPoint point = socket.LocalEndPoint as IPEndPoint;
                 LocalHost        = point.Address.ToString();
             }
             token.IPAddress = IPAddress.Parse(LocalHost);
             token.Remote    = endPoint;
             token.Socket    = socket;
             token.Client    = this;
             ReceiveClientData(token, buff);
         });
     }
 }
Beispiel #13
0
 private void Server_ClientNumberChange(int num, AsyncTcpUserToken token)
 {
     if (num > 0)
     {
         token.DataTime = DateTime.Now;
         if (token.TokenID == 0)
         {
             token.TokenID             = Interlocked.Increment(ref clientID);
             dic_Client[token.TokenID] = token;
         }
     }
     else
     {
         AsyncTcpUserToken tmp = null;
         dic_Client.TryRemove(token.TokenID, out tmp);
     }
     if (ClientNumberChange != null)
     {
         ClientNumberChange(num, token);
     }
 }
Beispiel #14
0
        /// <summary>
        /// 发送心跳
        /// </summary>
        /// <param name="token"></param>
        public void SendHeart(AsyncTcpUserToken token)
        {
            bool isSucess = false;

            if (token.Socket.Connected)
            {
                try
                {
                    token.Socket.Send(HeartServer);
                    isSucess = true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            if (!isSucess)
            {
                CloseClient(token);
            }
        }
Beispiel #15
0
 /// <summary>
 /// 发送数据;从缓存中来的数据
 /// </summary>
 /// <param name="token">客户端连接</param>
 /// <param name="entity">发送的缓存实体</param>
 /// <param name="flage">标记,默认null表示发送继续使用客户端缓存发送,否则由服务端分包使用服务端缓存发送</param>
 public void SendData(AsyncTcpUserToken token, CacheEntity entity, string flage = null)
 {
     if (string.IsNullOrEmpty(flage))
     {
         //继续使用客户端缓存发送,不能分包使用服务端缓存
         SocketAsyncEventArgs sendArg = new SocketAsyncEventArgs();
         sendArg.Completed += this.IO_Completed;
         sendArg.SetBuffer(entity.Buffer, entity.Offset, entity.Length);
         token.UserInfo             = Interlocked.Increment(ref entityid).ToString();
         dic_Entity[token.UserInfo] = entity;
         sendArg.UserToken          = token;
         if (token.Socket.SendAsync(sendArg))
         {
             ProcessSend(sendArg);
         }
     }
     else
     {
         SendMessage(token, entity.Buffer);
         entity.Dispose();
     }
 }
Beispiel #16
0
 /// <summary>
 /// 关闭客户端
 /// </summary>
 /// <param name="token"></param>
 public void CloseClient(AsyncTcpUserToken token)
 {
     server.CloseClient(token);
 }
Beispiel #17
0
 /// <summary>
 /// 对数据按照服务端缓存分包
 /// 然后发送
 /// </summary>
 /// <param name="token"></param>
 /// <param name="message"></param>
 /// <returns></returns>
 public void SendMessage(AsyncTcpUserToken token, byte[] message)
 {
     if (token == null || token.Socket == null || !token.Socket.Connected)
     {
         return;
     }
     try
     {
         //token.Socket.Send(buff);  //这句也可以发送, 可根据自己的需要来选择
         //新建异步发送对象, 发送消息
         int index = 0;
         int len   = 0;
         do
         {
             SocketAsyncEventArgs sendArg = m_pool.Pop();
             if (null == sendArg.UserToken)
             {
                 //说明是新建
                 sendArg.Completed += this.IO_Completed;
                 //m_bufferManager.SetBuffer(sendArg);
                 if (IsFixCacheSize) //分配缓存
                 {
                     m_bufferManager.SetBuffer(sendArg);
                 }
                 else
                 {
                     m_bufferManager.GetBuffer(sendArg);
                 }
             }
             sendArg.UserToken = token;
             byte[] buf    = sendArg.Buffer;
             int    curLen = message.Length - index;
             if (curLen < sendArg.Count)
             {
                 //重新开辟缓存,原缓存不合适
                 if (sendArg.Buffer != null)
                 {
                     if (IsFixCacheSize) //分配缓存
                     {
                         m_bufferManager.FreeBuffer(sendArg);
                     }
                     else
                     {
                         m_bufferManager.FreePoolBuffer(sendArg);
                     }
                 }
                 sendArg.SetBuffer(new byte[curLen], 0, curLen);
                 Array.Copy(message, index, sendArg.Buffer, sendArg.Offset, curLen);
                 index += curLen;
                 if (token.Socket.SendAsync(sendArg))
                 {
                     ProcessSend(sendArg);
                 }
             }
             else
             {
                 len = sendArg.Count;
                 Array.Copy(message, index, buf, sendArg.Offset, len);
                 index += len;
                 if (token.Socket.SendAsync(sendArg))
                 {
                     ProcessSend(sendArg);
                 }
             }
         } while (index >= message.Length);
     }
     catch (Exception e)
     {
         Console.WriteLine(e.Message);
     }
 }