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