You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:59:38