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); }
/// <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); }