MacOS Sonoma下用IdIcmpClient遇SOCKET ERROR #1,Windows正常
MacOS Sonoma下Indy IdIcmpClient执行Ping报“SOCKET ERROR #1”问题
问题详情
在MacOS Sonoma系统中使用Indy组件的IdIcmpClient执行Ping操作时,出现SOCKET ERROR #1错误,但相同的FMX代码在Windows系统下可正常运行,且已关闭MacOS主机防火墙。
相关代码
procedure TFrame_PingIPDomain.PingIPDomain; begin memOutput.Lines.Clear; IdIcmpClient.ReceiveTimeout := Round(sbTimeout.Value); // IdIcmpClient.PacketSize := Round(sbPacketSize.Value); IdIcmpClient.Host := edtIPDomain.Text; memOutput.Lines.Add('Pings:'); memOutput.Lines.Add('======================================'); var AvgTime: Double := 0.0; var PingTimes := TList<Double>.Create; for var I := 1 to Round(sbPingCount.Value) do begin IdIcmpClient.Ping(); if IdIcmpClient.ReplyStatus.ReplyStatusType = rsEcho then begin var RoundTripTime := IdIcmpClient.ReplyStatus.MsRoundTripTime; PingTimes.Add(RoundTripTime); memOutput.Lines.Add('Reply from ' + IdIcmpClient.ReplyStatus.FromIpAddress + ': time=' + RoundTripTime.ToString + 'ms'); end else if IdIcmpClient.ReplyStatus.ReplyStatusType = rsTimeout then memOutput.Lines.Add('Ping request timed out') else memOutput.Lines.Add('Ping request failed'); end; PingTimes.Sort; for var I := 1 to PingTimes.Count-1 do AvgTime := AvgTime + PingTimes.Items[I]; AvgTime := AvgTime / PingTimes.Count; memOutput.Lines.Add('======================================'); memOutput.Lines.Add('Statistics:'); memOutput.Lines.Add('======================================'); memOutput.Lines.Add('Min Time: ' + PingTimes.First.ToString + 'ms'); memOutput.Lines.Add('Max Time: ' + PingTimes.Last.ToString + 'ms'); memOutput.Lines.Add('Avg Time: ' + AvgTime.ToString + 'ms'); end;
错误提示
SOCKET ERROR #1
解决方法
1. 升级Indy组件版本
MacOS Sonoma对网络套接字操作有更严格的限制,旧版本Indy可能未适配系统变化。确保使用10.6.2.5490及以上版本的Indy组件,该版本修复了多个MacOS平台的网络兼容性问题。
2. 解决ICMP权限限制
MacOS下执行ICMP Ping需要特殊权限:
- 开发阶段:以管理员权限启动Delphi等IDE(右键IDE图标,按住Option键选择“以管理员身份打开”)。
- 发布阶段:给程序二进制文件添加
setuid权限,打开终端定位到程序目录,执行:
该操作需要管理员密码,会让程序以root权限运行,仅用于需ICMP操作的场景。sudo chmod u+s YourAppName.app/Contents/MacOS/YourAppName
3. 调整组件参数设置
- 显式指定IP版本,避免自动检测的兼容性问题:
IdIcmpClient.Binding.IPVersion := Id_IPv4; // 或Id_IPv6,根据目标地址选择 - 取消注释
PacketSize设置,确保数据包大小符合系统要求:IdIcmpClient.PacketSize := Round(sbPacketSize.Value);
4. 捕获详细异常信息
在Ping()调用外添加异常捕获,获取更精准的错误原因:
try IdIcmpClient.Ping(); except on E: Exception do memOutput.Lines.Add('Error detail: ' + E.Message); end;
内容的提问来源于stack exchange,提问作者Gorhin Stroebel
相关产品推荐
相关产品推荐

