Lidgren.Network.NetException异常:「消息已发送」报错原因分析
为什么会触发Lidgren的NetException?
嘿,这个问题我太熟悉了!你遇到的这个异常,核心原因是Lidgren的NetOutgoingMessage实例是设计为单次使用的。
当你第一次调用Server.SendMessage(outmsg, Player1Connection, ...)时,Lidgren会把这个消息实例加入到发送队列,同时内部会将它标记为“已发送”状态——这是为了优化内存使用(比如重用消息池里的对象),但代价就是同一个消息实例不能被重复调用SendMessage。你紧接着用同一个outmsg给Player2Connection发送,自然就触发了这个异常提示。
解决方法
这里有两个简单又高效的修复方案:
方案1:使用多收件人重载(推荐)
Lidgren本身就支持一次把消息发送给多个连接,这不仅能解决重复使用消息的问题,还更符合官方推荐的高效发送方式。你可以直接把多个连接放到数组里传入:
else if (CounfOfPlayers == 1) { Player2Connection = inc.SenderConnection; Console.WriteLine(Player2Connection.RemoteEndPoint.ToString()); CounfOfPlayers++; Console.WriteLine("Accepted second player"); outmsg.Write((byte)PacketType.RDY); // 一次发送给两个连接 Server.SendMessage(outmsg, new NetConnection[] { Player1Connection, Player2Connection }, NetDeliveryMethod.ReliableOrdered, 0); }
方案2:每次发送创建新的消息实例
如果因为某些原因你需要分开发送,那每次发送前都要创建新的NetOutgoingMessage:
else if (CounfOfPlayers == 1) { Player2Connection = inc.SenderConnection; Console.WriteLine(Player2Connection.RemoteEndPoint.ToString()); CounfOfPlayers++; Console.WriteLine("Accepted second player"); // 给Player1发的消息 var msgToPlayer1 = Server.CreateMessage(); msgToPlayer1.Write((byte)PacketType.RDY); Server.SendMessage(msgToPlayer1, Player1Connection, NetDeliveryMethod.ReliableOrdered); // 给Player2发的消息 var msgToPlayer2 = Server.CreateMessage(); msgToPlayer2.Write((byte)PacketType.RDY); Server.SendMessage(msgToPlayer2, Player2Connection, NetDeliveryMethod.ReliableOrdered); }
小提示
记住,Lidgren的消息对象是和发送状态绑定的,不管是NetOutgoingMessage还是NetIncomingMessage,都不要重复使用已发送/已处理的实例,尽量用官方提供的重载或者每次创建新实例来避免这类问题。
内容的提问来源于stack exchange,提问作者user280179
相关产品推荐
相关产品推荐

