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

使用Indy的TIdTraceRoute追踪路由时遇Socket Error #10040问题求助

使用Indy TIdTraceRoute组件追踪路由时触发Socket Error #10040错误

触发异常:EIdSocketError,错误信息:'Socket Error # 10040 Message too long.'

组件设计时属性

object IdTraceRoute: TIdTraceRoute
    ReceiveTimeout = 5000
    Protocol = 1
    ProtocolIPv6 = 58
    ResolveHostNames = True
    OnReply = IdTraceRouteReply
    Left = 640
    Top = 472
  end

代码实现

procedure TFrame_TraceRoute.TraceRoute;
begin
  memOutput.Lines.Clear;

  IdTraceRoute.ReceiveTimeout := Round(sbTimeout.Value);
  IdTraceRoute.PacketSize := Round(sbPacketSize.Value);
  IdTraceRoute.Host := edtIPDomain.Text;

  memOutput.Lines.Add('Pings:');
  memOutput.Lines.Add('======================================');

  IdTraceRoute.Trace();
end;

procedure TFrame_TraceRoute.IdTraceRouteReply(ASender: TComponent; const AReplyStatus: TReplyStatus);
begin
  if AReplyStatus.ReplyStatusType = rsEcho then
  begin
    var RoundTripTime := AReplyStatus.MsRoundTripTime;
    memOutput.Lines.Add('Reply from ' + AReplyStatus.FromIpAddress + ': time=' + RoundTripTime.ToString + 'ms');
  end
  else if AReplyStatus.ReplyStatusType = rsTimeout then
    memOutput.Lines.Add('Ping request timed out')
  else
    memOutput.Lines.Add('Ping request failed');
end;

错误在调用IdTraceRoute.Trace()时立即触发。我尝试过参考同类错误的解决方案,将PacketSize设置到24甚至更小,但问题依旧。使用相同属性配置的TIdIcmpClient执行Ping操作完全正常,仅切换到TIdTraceRoute时出现该错误。请问问题出在哪里?错误原因可能是什么?


解答

错误核心原因

Socket Error #10040表示发送的数据包总长度超过了底层网络的MTU(最大传输单元)限制。你遇到的问题根源在于TIdTraceRoute和TIdIcmpClient对PacketSize参数的定义不同:

  • TIdIcmpClient的PacketSize包含了ICMP头的长度,实际发送的总长度是该值加上IP头长度;
  • 而TIdTraceRoute的PacketSize仅指数据包的payload部分,组件会自动额外添加IP头(约20字节)和ICMP头(8字节),最终总长度=PacketSize+28。你设置的数值即使很小,若组件内部存在计算偏差或版本bug,仍可能导致总长度超限。

可行解决方案

  1. 精准设置PacketSize
    按照「总长度不超过MTU(以太网默认1500)」倒推:总长度=IP头(20)+ICMP头(8)+Payload,所以最大Payload应为1472。若要测试极小数据包,将PacketSize设为0即可(此时总长度为28字节,刚好是最小ICMP包尺寸)。

  2. 检查组件版本与配置

    • 确认使用的是Indy最新稳定版,旧版本的TIdTraceRoute存在数据包长度计算的bug;
    • 若目标主机是IPv6环境,确保ProtocolIPv6=58(ICMPv6)的配置正确,同时目标地址为有效IPv6地址。
  3. 代码层面强制限制
    在设置PacketSize时手动做上限控制,避免超限:

    // 限制Payload最大为1472,确保总长度不超过1500
    IdTraceRoute.PacketSize := Min(Round(sbPacketSize.Value), 1472);
    

内容的提问来源于stack exchange,提问作者Shaun Roselt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 04:07:25