重金求助老司机,局域网探测是否开关机,使用TClientSocket,TServerSoket,TIdICMPClient遇到问题

一本假正经 2017-09-08 07:52:14
现在有一个服务端主机,需要实时探测局域网主机(1000台以内)的开关机状态,并且需要和他们通信。现在的思路是:

服务端:安装服务端软件,有一个TServerSoket组件(stNonBlocking模式),负责和所有服务机通信,还有一个TIdICMPClient,周期性ping各客户机IP
客户机:安装客户机软件,随机启动,有一个TClientSocke组件,主动连接TServerSoket。

现在的问题是:

1 服务端ping各客户机不稳定,大部分时间能ping通,有时不能ping通;
2 TServerSoket的read事件中可能会有异常。

求老司机帮助啊。
...全文
1524 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
我来加点人气:范大师都八级了....
newpeng 2018-01-08
  • 打赏
  • 举报
回复
一个月之前的帖子?这个版人气好低。
newpeng 2018-01-08
  • 打赏
  • 举报
回复
自己用socket写server和client,何必 TIdICMPClient。 思路如下: 服务器server开启端口一直侦听,客户端卡机及运行client,向服务器注册并定时发送心跳包,同时自己也开启端口侦听,服务器端得到客户端的注册信息之后,一直接收客户端来的心跳包,如果超过多长时间没有收到,可以反过去连接客户端端口,或者ping客户端也行【调用系统的ping简单吧】。 当然,如果client太多,建议用短链接。
lyhoo163 2018-01-08
  • 打赏
  • 举报
回复
人气靠大家!!!
Bone_storm 2018-01-08
  • 打赏
  • 举报
回复
引用 17 楼 newpeng 的回复:
一个月之前的帖子?这个版人气好低。
9月份发的帖了。。。。 Delphi真是没人气。
SupermanTm 2017-11-30
  • 打赏
  • 举报
回复
这种应用最好采用 UDP 发个心跳包,根本不建立连接,超过多少时间没心跳包就判为关机就可以了 1000台以上机器,如果TCP的话,你的交换机负荷就不少,UDP比较正道。 如果用 winsock 的话,这个 UDP 也不需要什么控件,直接用Winsock库里的几个函数就解决了
qiankunbobo 2017-11-29
  • 打赏
  • 举报
回复
有个应用层的协议叫SNMP。很多设备包括主机、服务器、交换机、路由器、打印机都支持该协议。 通过这个协议,做trap能间隔向指定的IP地址发送状态信息。 通过该协议还能画出网络中的拓扑图出来。甚至得知交换机端口的状态。
nm_wyh 2017-11-28
  • 打赏
  • 举报
回复
另外可以考虑WebSocket连接试试,不过这个可能服务器压力比较大!而且不过是那种方式并不能确定对方是关机,可能客户端软件关掉也会中断通讯。这种情况下可以用telnet来判断是否关机也可以。
  • 打赏
  • 举报
回复
你是要探测局域网中某些IP的电脑是否开机,还是要检测局域网内某些电脑上你的客户端软件是否运行,这两者并不完全等同。 如果是前者,不要用ping,因为防火墙设置可以不响应ping,可以用SendARP获取对方的物理地址(MAC地址),如果成功则对方电脑是联网的,为了防止vista或者之后的windows使用本地缓存的ARP表,可以先DeleteIpNetEntry再SendARP。 如果是后者,客户端软件可以监听一个端口,如果接收到特定的握手数据(自己定义),就返回一个特定的回应,这样服务端轮询局域网内的IP,就可以知道哪些客户端启动了。
一本假正经 2017-10-31
  • 打赏
  • 举报
回复
感谢各位的回复,我试试 SendARP 方法。
hongss 2017-10-31
  • 打赏
  • 举报
回复
心跳是常用做法
jinhx 2017-10-31
  • 打赏
  • 举报
回复
建议用IdIPMCast,客户端隔几秒报告自己的状态,报告关机的就是关机状态,超时不报告的就是失联
lyhoo163 2017-10-31
  • 打赏
  • 举报
回复
建议在客户端建立心跳,服务器接收心跳信息。比如心跳3分钟一次。 服务器端处理: 1、建立一客户端的列表,记录IP和用户名、心跳时间。 2、接收到的数据,对比客户端的列表,如无就新增,有就更新心跳时间。 3、定时扫描客户端的列表,心跳时间超过3分钟未接收,确定下线,从列表中删除。
wanyunyi 2017-10-30
  • 打赏
  • 举报
回复
我也在做同样的功能,我是调WINDOWS的API来实现PING的
一本假正经 2017-09-11
  • 打赏
  • 举报
回复
现在看第1步,服务端主动ping 也不算是多余的,因为可能出现 客户端不随机启动,或者延迟几分钟启动的情况。 客户机数量众多(100--1000),不由我控制,我的客户端程序是免安装的,由别人放到客户机上,设置开机启动项。
一本假正经 2017-09-11
  • 打赏
  • 举报
回复
感谢两位的回复。 开始我的思路是双管齐下: 1 服务端主动使用TIdICMPClient.ping探测各客户机的开关机状态(开机要及时知道,关机也要及时知道。现在会出问题:明明开机,在CMD下能ping通,我的程序却报异常:Socket Erro 10040:Message too long,有的说是TIdICMPClient不支持多线程,有的说是Indy的bug,还没找到解决办法); 2 客户端开机后自启动,主动给服务端发心跳,获取自己的最新状态(程序需求,客户端可能已经被预定,如果被预定,客户端要跳出来全屏锁屏,不让别人用)。同时,服务端只要收到了客户机的心跳,就证明客户机肯定是开机的。 现在看来,第1条,服务端主动开多线程(每台客户机一个线程,根据IP)ping客户机是多余的了。下面是我的ping方法,在线程里调用,还请指正。

{测试IP地址能否PING通}
function ping(url: string): Boolean;
var
  i: Integer;
  rst: Boolean;
  err: String;
  icmpClient: TIdICMPClient;
begin
  i:= 0;
  rst:= False;
  icmpClient:= TIdICMPClient.Create(nil);
  icmpClient.ReceiveTimeout:= 500;
  icmpClient.Host:= url;
  icmpClient.PacketSize:= 1024;
  //ABuffer := url+ StringOfChar(' ', 255);

  while (not rst) and (i<3) do
  begin
    inc(i);
    try
      icmpClient.Ping();
      Application.ProcessMessages;
      if (icmpClient.ReplyStatus.FromIpAddress = url) then
      begin
        rst:= True;
      end
      else
      begin
        rst:= false;
        sleep(10);
      end;
    except
      on e: Exception do
      begin
        err:= e.Message;
        //Socket Error # 10040 Message too long.是ping不通时的正常超时异常
        if pos('10040',err)=0 then
          Logger.Log(url+' Ping异常:'+ err);
        rst:= False;
        sleep(10);
      end;
    end;

  end;

  Result:= rst;
  icmpClient.Free;

end;
lizjf 2017-09-10
  • 打赏
  • 举报
回复
你判断的是开关机状态,不是通不通网状态,如果开机但是网不通呢,心跳包传不过来就代表关机就行了啊
一本假正经 2017-09-09
  • 打赏
  • 举报
回复
引用 1 楼 lyhoo163 的回复:
利用心跳,建立联系。
大哥,能够给个联系方式,我付费请教些问题,例如: 我在线程中使用 TIdICMPClient.ping 主机,但是不稳定,有时明明开机,却ping不通。 也可以加我QQ: 306068056,谢谢了。
一本假正经 2017-09-08
  • 打赏
  • 举报
回复
引用 1 楼 lyhoo163 的回复:
利用心跳,建立联系。
我现在的做法就是这样,只要客户端启动了,就每隔n秒给服务端发个消息
lyhoo163 2017-09-08
  • 打赏
  • 举报
回复
利用心跳,建立联系。

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧