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);
        }
Beispiel #2
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);
        }