使用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,仍可能导致总长度超限。
可行解决方案
精准设置PacketSize
按照「总长度不超过MTU(以太网默认1500)」倒推:总长度=IP头(20)+ICMP头(8)+Payload,所以最大Payload应为1472。若要测试极小数据包,将PacketSize设为0即可(此时总长度为28字节,刚好是最小ICMP包尺寸)。检查组件版本与配置
- 确认使用的是Indy最新稳定版,旧版本的
TIdTraceRoute存在数据包长度计算的bug; - 若目标主机是IPv6环境,确保
ProtocolIPv6=58(ICMPv6)的配置正确,同时目标地址为有效IPv6地址。
- 确认使用的是Indy最新稳定版,旧版本的
代码层面强制限制
在设置PacketSize时手动做上限控制,避免超限:// 限制Payload最大为1472,确保总长度不超过1500 IdTraceRoute.PacketSize := Min(Round(sbPacketSize.Value), 1472);
内容的提问来源于stack exchange,提问作者Shaun Roselt
相关产品推荐
相关产品推荐

