public void TrySendAll()
        {
            List <TMSKSocket> lsSocket = new List <TMSKSocket>(2000);

            while (!this._Exit)
            {
                lsSocket.Clear();
                lock (this.BufferDict)
                {
                    lsSocket.AddRange(this.BufferDict.Keys);
                }
                int lsSocketCount = lsSocket.Count;
                for (int i = 0; i < lsSocketCount; i++)
                {
                    TMSKSocket s = lsSocket[i];
                    if (null != s)
                    {
                        SendBuffer sendBuffer = s._SendBuffer;
                        bool       bFind      = sendBuffer != null;
                        if (bFind && null != sendBuffer)
                        {
                            sendBuffer.ExternalTrySend(s, true, 0);
                        }
                        if (s.DelayClose > 0 && s.DelayClose-- <= 0)
                        {
                        }
                    }
                }
                Thread.Sleep(20);
            }
        }
Exemple #2
0
        /// <summary>
        /// 发送成功
        /// </summary>
        /// <param name="s"></param>
        public void OnSendBufferOK(TMSKSocket s)
        {
            if (GameManager.FlagOptimizeLock)
            {
                SendBuffer sendBuffer = s._SendBuffer;
                if (null != sendBuffer)
                {
                    sendBuffer.OnSendOK();
                }
            }
            else
            {
                SendBuffer sendBuffer;
                lock (BufferDict)
                {
                    BufferDict.TryGetValue(s, out sendBuffer);
                }

                if (null != sendBuffer)
                {
                    sendBuffer.OnSendOK();
                }
            }

            if (!GameManager.FlagOptimizeLockTrace)
            {
                Global._FullBufferManager.Remove(s);
            }
        }
Exemple #3
0
        /// <summary>
        /// 移除相应套接字的缓存
        /// </summary>
        /// <param name="s"></param>
        public void Remove(TMSKSocket s)
        {
            SendBuffer sendBuffer = null;

            lock (BufferDict)
            {
                if (BufferDict.TryGetValue(s, out sendBuffer))
                {
                    BufferDict.Remove(s);
                    if (GameManager.FlagOptimizeLock)
                    {
                        s._SendBuffer = null;
                    }
                }
            }

            //在外部调用,多线程重复也无所谓
            if (null != sendBuffer)
            {
                if (GameManager.FlagOptimizeThreadPool2)
                {
                    TMSKThreadStaticClass.GetInstance().PushMemoryBlock(sendBuffer.MyMemoryBlock);
                }
                else
                {
                    Global._MemoryManager.Push(sendBuffer.MyMemoryBlock);
                }
            }

            if (!GameManager.FlagOptimizeLockTrace)
            {
                Global._FullBufferManager.Remove(s);
            }
        }
        public void OnSendBufferOK(TMSKSocket s)
        {
            SendBuffer sendBuffer = s._SendBuffer;

            if (null != sendBuffer)
            {
                sendBuffer.OnSendOK();
            }
            Global._FullBufferManager.Remove(s);
        }
 public void Add(TMSKSocket s)
 {
     lock (this.BufferDict)
     {
         if (!this.BufferDict.ContainsKey(s))
         {
             SendBuffer sendBuffer = new SendBuffer(0);
             s._SendBuffer = sendBuffer;
             this.BufferDict.Add(s, sendBuffer);
         }
     }
 }
Exemple #6
0
 /// <summary>
 /// 添加套接字的缓存
 /// </summary>
 /// <param name="s"></param>
 public void Add(TMSKSocket s)
 {
     lock (BufferDict)
     {
         if (!BufferDict.ContainsKey(s))
         {
             SendBuffer sendBuffer = new SendBuffer();
             if (GameManager.FlagOptimizeLock)
             {
                 s._SendBuffer = sendBuffer;
             }
             BufferDict.Add(s, sendBuffer);
         }
     }
 }
        public bool AddOutPacket(TMSKSocket s, TCPOutPacket tcpOutPacket)
        {
            SendBuffer sendBuffer = s._SendBuffer;
            bool       result;

            if (null == sendBuffer)
            {
                result = false;
            }
            else
            {
                int  canNotSendReason = -1;
                bool bRet             = sendBuffer.CanSend2(s, tcpOutPacket, ref canNotSendReason);
                if (!bRet)
                {
                    if (sendBuffer.CanLog(canNotSendReason))
                    {
                        string failedReason = FullBufferManager.GetErrorStr(canNotSendReason);
                        LogManager.WriteLog(LogTypes.Error, string.Format("向客户端{0}发送数据失败, 发送指令:{1}, 大小:{2}, 失败原因:{3}", new object[]
                        {
                            Global.GetSocketRemoteEndPoint(s, false),
                            (TCPGameServerCmds)tcpOutPacket.PacketCmdID,
                            tcpOutPacket.PacketDataSize,
                            failedReason
                        }), null, true);
                    }
                    Global._FullBufferManager.Add(s, canNotSendReason);
                    result = (canNotSendReason == 0);
                }
                else
                {
                    if (tcpOutPacket.PacketDataSize > this.MaxOutPacketSize)
                    {
                        this.MaxOutPacketSize      = tcpOutPacket.PacketDataSize;
                        this.MaxOutPacketSizeCmdID = (int)tcpOutPacket.PacketCmdID;
                    }
                    if (!bRet)
                    {
                        LogManager.WriteLog(LogTypes.Error, string.Format("向客户端{0}发送数据时加入缓存失败, 缓存空间不足, 发送指令:{1}, 大小:{2}", Global.GetSocketRemoteEndPoint(s, false), (TCPGameServerCmds)tcpOutPacket.PacketCmdID, tcpOutPacket.PacketDataSize), null, true);
                    }
                    result = bRet;
                }
            }
            return(result);
        }
        public void Remove(TMSKSocket s)
        {
            SendBuffer sendBuffer = null;

            lock (this.BufferDict)
            {
                if (this.BufferDict.TryGetValue(s, out sendBuffer))
                {
                    this.BufferDict.Remove(s);
                    s._SendBuffer = null;
                }
            }
            if (null != sendBuffer)
            {
                Global._MemoryManager.Push(sendBuffer.MyMemoryBlock);
            }
            Global._FullBufferManager.Remove(s);
        }
Exemple #9
0
        /// <summary>
        /// 添加输出数据包
        /// </summary>
        /// <param name="s"></param>
        /// <param name="tcpOutPacket"></param>
        /// <returns></returns>
        public bool AddOutPacket(TMSKSocket s, TCPOutPacket tcpOutPacket)
        {
            bool bRet;
            //发出去的信息不再进行加密处理, 客户端的接受也修改为不做解密处理
            //字节排序
            //DataHelper.SortBytes(tcpOutPacket.GetPacketBytes(), 0, tcpOutPacket.PacketDataSize);

            SendBuffer sendBuffer = null;

            if (GameManager.FlagOptimizeLock)
            {
                sendBuffer = s._SendBuffer;
                if (null == sendBuffer)
                {
                    return(false);
                }
            }
            else
            {
                lock (BufferDict)
                {
                    if (!BufferDict.TryGetValue(s, out sendBuffer))
                    {
                        //sendBuffer = new SendBuffer();
                        //lock (BufferDict)
                        //{
                        //    BufferDict.Add(s, sendBuffer);
                        //}
                        //不要在这儿动态添加,外部调用这个函数的时机很复杂,可能会在连接断开之后再调用,产生死socket的缓存
                        return(false);
                    }
                }
            }

            int canNotSendReason = -1;

            if (GameManager.FlagOptimizeThreadPool4)
            {
                bRet = sendBuffer.CanSend2(s, tcpOutPacket, ref canNotSendReason);
            }
            else
            {
                bRet = sendBuffer.CanSend(tcpOutPacket.PacketDataSize, tcpOutPacket.PacketCmdID, out canNotSendReason, tcpOutPacket.GetPacketBytes(), s);
            }
            if (!bRet)
            {
                //避免大量的重复日志记录
                if (sendBuffer.CanLog(canNotSendReason))
                {
                    string failedReason = FullBufferManager.GetErrorStr(canNotSendReason);
                    LogManager.WriteLog(LogTypes.Error, string.Format("向客户端{0}发送数据失败, 发送指令:{1}, 大小:{2}, 失败原因:{3}", Global.GetSocketRemoteEndPoint(s), (TCPGameServerCmds)tcpOutPacket.PacketCmdID, tcpOutPacket.PacketDataSize, failedReason));
                }

                if (!GameManager.FlagOptimizeLockTrace)
                {
                    Global._FullBufferManager.Add(s, canNotSendReason);
                }
                return(canNotSendReason == (int)FullBufferManager.Error_SendTimeOut);  //如果等于超时就返回true, 让外边不再频繁记日志,只有丢弃的包才让外边也记日志
            }

            //加入发送缓存
            //bRet = sendBuffer.AddBuffer(tcpOutPacket.GetPacketBytes(), 0, tcpOutPacket.PacketDataSize, s);

            //记录发出的最大数据包
            if (tcpOutPacket.PacketDataSize > MaxOutPacketSize)
            {
                MaxOutPacketSize      = tcpOutPacket.PacketDataSize;
                MaxOutPacketSizeCmdID = tcpOutPacket.PacketCmdID;
            }

            //返回错误,应该是缓冲区满,立即发送
            if (!bRet)
            {
                LogManager.WriteLog(LogTypes.Error, string.Format("向客户端{0}发送数据时加入缓存失败, 缓存空间不足, 发送指令:{1}, 大小:{2}", Global.GetSocketRemoteEndPoint(s), (TCPGameServerCmds)tcpOutPacket.PacketCmdID, tcpOutPacket.PacketDataSize));

                /*
                 * //这儿不用再判断数据是否发送成功
                 * sendBuffer.TrySend(s, true);
                 * //if (sendBuffer.TrySend(s, true))
                 * //{
                 *  //发送完毕之后,再尝试添加缓冲数据
                 *  bRet = sendBuffer.AddBuffer(tcpOutPacket.GetPacketBytes(), 0, tcpOutPacket.PacketDataSize);
                 *
                 *  //如果添加失败,则直接发送----对于大数据有用
                 *  if (!bRet)
                 *  {
                 *      int nSendLen = tcpOutPacket.PacketDataSize;
                 *      //System.Diagnostics.Debug.WriteLine("SendBufferManager 某些数据包太大,直接发送 tcpOutPacket.PacketDataSize== " + tcpOutPacket.PacketDataSize);
                 *
                 *      //如果还失败,直接发送--->异步发送的时候是拷贝了内存,如果内存块是被管理的,这儿就多拷贝一次
                 *      if (!tcpOutPacket.MyMemoryBlock.isManaged)
                 *      {
                 *          //对于不受管理的内存,这儿直接发送
                 *          bRet = Global._TCPManager.MySocketListener.SendData(s, tcpOutPacket.GetPacketBytes(), 0, tcpOutPacket.PacketDataSize, null);
                 *      }
                 *      else
                 *      {
                 *          //对于受管理的内存,考虑到tcpOutPacket会还回内存池,该内存可能会被用做其他用途,导致混乱,这儿重新拷贝一份
                 *          MemoryBlock block = Global._MemoryManager.Pop(nSendLen);
                 *          DataHelper.CopyBytes(block.Buffer, 0, tcpOutPacket.GetPacketBytes(), 0, nSendLen);
                 *
                 *          bRet = Global._TCPManager.MySocketListener.SendData(s, block.Buffer, 0, nSendLen, block);
                 *      }
                 *  }
                 * //}
                 */
            }

            return(bRet);
        }
Exemple #10
0
        /// <summary>
        /// 尝试发送所有的数据包
        /// </summary>
        public void TrySendAll()
        {
            //最大睡眠时间 毫秒
            //int maxSleepMiniSecs = 1;
            //int  sleepMiniSecs = 0;
            List <TMSKSocket> lsSocket   = new List <TMSKSocket>(2000);
            SendBuffer        sendBuffer = null;
            bool bFind = false;

            while (!_Exit)
            {
                lsSocket.Clear();

                //System.Diagnostics.Debug.WriteLine("SendBufferManager BufferDict.Count == " + BufferDict.Count);
                //遍历需要加锁吗?当这儿拿到一个buffer,Remove同时被触发,这儿的buffer仍然是有效的,最多产生异常
                //long preTicks = TimeUtil.NOW();

                //保证锁住BufferDict的时间很小
                lock (BufferDict)
                {
                    lsSocket.AddRange(BufferDict.Keys);
                }

                int lsSocketCount = lsSocket.Count;
                //foreach (var s in lsSocket)
                for (int i = 0; i < lsSocketCount; i++)
                {
                    TMSKSocket s = lsSocket[i];
                    if (null == s)
                    {
                        continue;
                    }

                    if (GameManager.FlagOptimizeLock)
                    {
                        sendBuffer = s._SendBuffer;
                        bFind      = (sendBuffer != null);
                    }
                    else
                    {
                        lock (BufferDict)
                        {
                            bFind = BufferDict.TryGetValue(s, out sendBuffer);
                        }
                    }

                    if (bFind && null != sendBuffer)
                    {
                        sendBuffer.ExternalTrySend(s, true, 0); //尝试发送,如果锁定超时,继续处理下边的指令
                    }
                }
                //foreach (var buffer in BufferDict)
                //{
                //    buffer.Value.TrySend(buffer.Key);
                //}

                /*int usedTicks = (int)(TimeUtil.NOW() - preTicks);
                 *
                 * sleepMiniSecs = Math.Max(1, maxSleepMiniSecs - usedTicks);
                 * if (sleepMiniSecs > 0)
                 * {
                 *  Thread.Sleep(sleepMiniSecs);
                 * }*/

                Thread.Sleep(20);
            }
        }
        /// <summary>
        /// 向客户端发送数据
        /// </summary>
        /// <param name="data"></param>
        public bool SendData(TMSKSocket s, Byte[] buffer, int offset, int count, MemoryBlock item, SendBuffer sendBuffer)
        {
            GTotalSendCount++;
            SocketAsyncEventArgs writeEventArgs;

            if (GameManager.FlagOptimizeThreadPool3)
            {
                writeEventArgs = s.PopWriteSocketAsyncEventArgs(); //线程安全的操作
            }
            else
            {
                writeEventArgs = this.writePool.Pop(); //线程安全的操作
            }
            if (null == writeEventArgs)
            {
                writeEventArgs            = new SocketAsyncEventArgs();
                writeEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnIOCompleted);
                writeEventArgs.UserToken  = new AsyncUserToken()
                {
                    CurrentSocket = null, Tag = null
                };
            }

            writeEventArgs.SetBuffer(buffer, offset, count);
            AsyncUserToken userToken = (writeEventArgs.UserToken as AsyncUserToken);

            userToken.CurrentSocket = s;
            userToken.Tag           = item;
            userToken._SendBuffer   = sendBuffer;

            bool exception = false;

            if (GameManager.FlagSkipSocketSend && GameManager.CanSkipCmd(s))
            {
                writeEventArgs.SocketError = SocketError.Success;
                this.ProcessSend(writeEventArgs);
            }
            else
            {
                Boolean willRaiseEvent = _SendAsync(writeEventArgs, out exception);
                if (!willRaiseEvent)
                {
                    this.ProcessSend(writeEventArgs);
                }
            }

            if (exception) //此处不处理会导致内存泄露
            {
                /// 发送数据通知函数
                if (null != SocketSended)
                {
                    SocketSended(this, writeEventArgs);
                }

                //什么事情都不做, 收回使用的e和buffer
                // Free the SocketAsyncEventArg so they can be reused by another client.
                writeEventArgs.SetBuffer(null, 0, 0); //回收内存
                userToken.CurrentSocket = null;       //释放
                userToken.Tag           = null;       //释放
                if (GameManager.FlagOptimizeThreadPool3)
                {
                    s.PushWriteSocketAsyncEventArgs(writeEventArgs);
                }
                else
                {
                    this.writePool.Push(writeEventArgs);
                }
            }

            return(!exception);
        }
Exemple #12
0
        public bool SendData(TMSKSocket s, byte[] buffer, int offset, int count, MemoryBlock item, SendBuffer sendBuffer)
        {
            this.GTotalSendCount++;
            SocketAsyncEventArgs writeEventArgs = s.PopWriteSocketAsyncEventArgs();

            if (null == writeEventArgs)
            {
                writeEventArgs            = new SocketAsyncEventArgs();
                writeEventArgs.Completed += this.OnIOCompleted;
                writeEventArgs.UserToken  = new AsyncUserToken
                {
                    CurrentSocket = null,
                    Tag           = null
                };
            }
            writeEventArgs.SetBuffer(buffer, offset, count);
            AsyncUserToken userToken = writeEventArgs.UserToken as AsyncUserToken;

            userToken.CurrentSocket = s;
            userToken.Tag           = item;
            userToken._SendBuffer   = sendBuffer;
            bool exception = false;

            if (!this._SendAsync(writeEventArgs, out exception))
            {
                this.ProcessSend(writeEventArgs);
            }
            if (exception)
            {
                if (null != this.SocketSended)
                {
                    this.SocketSended(this, writeEventArgs);
                }
                writeEventArgs.SetBuffer(null, 0, 0);
                userToken.CurrentSocket = null;
                userToken.Tag           = null;
                s.PushWriteSocketAsyncEventArgs(writeEventArgs);
            }
            return(!exception);
        }