INDY中IdUDPClient的问题,好苦恼....谁能帮帮我!!(300分)

  • 主题发起人 主题发起人 Final Code
  • 开始时间 开始时间
F

Final Code

Unregistered / Unconfirmed
GUEST, unregistred user!
编程中发现,IdUDPClient在数据接受方没有开机时,Send(或SendBuffer或Binding.SendTo)会停留很长时间,为什么?不是说UDP不管接受方是否存在吗?太郁闷了。请问如何解决,代码附下:
procedure TForm1.Button1Click(Sender: TObject);
const
TEXT = '123456790';
var
i: Integer;
szSendContent: string;
begin
// 初始化UDPClient
with IdUDPClient1 do
begin
Port := 2049;
Host := '192.168.1.215';
ReceiveTimeout := -2;
Active := True;
end;
// 组装要发送的数据
for i := 0 to 1024 do
szSendContent := szSendContent + TEXT;
while not chckbxTerminatel.Checked do
begin
Application.ProcessMessages();
IdUDPClient1.Send(szSendContent); // ????? 会在此句停留很长时间
end;
end;

注:请在Form中加入一个CheckBox,改名为chckbxTerminatel、加入一个Button、加入一个IdUDPClient。Indy版本:9.0.14,系统版本:Windows2000,Delphi版本:6.0(Update 2)
 
FIdUDPClient.ReceiveTimeout := 5000;
等5秒,别设成-2,设成个时间短点的数吧
 
试过了,设为100ms,没用呀。
 
不会,我的程序先用idUDPClient给本机发,如果没反应广播,都没问题,最多5秒
 
另外你这里没捕获异常,同时,98下不进入异常,你要特殊处理。
 
你试试给一个IP没开机的机器发送,等待5秒太长时间了,如果此IP开机,则发送也就用个几十毫秒。
再有,我的系统是Win2000。
谢谢!
 
我诗了,改成100毫秒,给一个不存在的机器发消息,只是点击check筐的时候稍微慢些,没什么问题啊,我的也是2000。
慢些也正常,大概两三秒钟才反应,不过,你的这个while循环会占用很多系统资源,两三秒钟已经不错了
 
你试试跟踪,当跟踪到Send语句时,会停留几秒钟呀。可是当接受端在线是就不会在Send语句有停留。
 
呵呵,我的内存是512,不知道你的是多少,我是跟踪的,基本上感觉不到等待,看来我帮不上什么忙了:)不过我试的都是不在线的。
 
我编写的是服务器软件,服务器会向客户端发送UDP包,如果客户端不在线,服务器每次在Send中等待几秒钟是不可取的,毕竟一个服务器要向几百个客户端发送数据。
还有,我的服务器是1G内存,双至强CPU。

再次谢谢cnsandboy
 
2 3秒可以了
 
To c20001231:
可是如果接受端在线,那么Send只用几十个毫秒。
 
而且如果用网络流量监控软件监控,此时发送的字节数为0kb/s
 
最后给你一个建议,新建一个应用程序,控件别用考的,从面板上拖过去,测,看时间。
呵呵,我这个破机器在接受端不在线的时候也没用了2秒,最多也就几十毫秒,所以我怀疑是其他原因,或者你也可以换个机器或者网络环境试试,不一定是软件问题。
 
谢谢!
只是我搞不明白,为什么在接受端不在线的时候,网络流量监控软件检测出IdUDPClient没有发送出去UDP包。当接收端一旦打开,一切都转好了,Send不用等待,网络流量监控软件也检测出有UDP包发送出去了。
要使按照TCP/IP协议,UDP是无连接的,发送UDP包和客户端在不在线无关。
跟踪到IdUDPClient等待的一句是在IdSocketWindows.pas中调用的Windows API中的SendTo(ASocket, ABuffer, ABufferLength, AFlags, @Addr, SizeOf(Addr)),这可是Windows API呀,在VC中这样写UDP就不用等待。真搞不懂......

 
神阿,救救我吧......
 
用我控件把,原因可能是TIdUDPClient可能是同步方式发送,而且
TIdUDPClient在发送包以后要判断一下对方的IP是否是存在的IP,
就是调用一下GetHostByAddr什么的,这个是比较消耗时间的查询
操作,所以TIdUDPClient发送的时候组塞是正常的.
我的空间在www.playicq.com上,如果要新版本的,给我发个MAIL
也行.sunhuiNO1@hotmail.com
 
谢谢,我马上试试。
 
给段代码你参考下,可能会领略到什么……
procedure TForm1.Button5Click(Sender: TObject);
type
tmsg=record
ip,memo:string[100];
end;
var
msg:tmsg;
begin
if (Edit2.text<>'') and (Edit3.Text<>'') and (Memo2.Text<>'') then
begin
msg.ip:=idIpWatch1.LocalIP;
msg.memo:=memo2.Text;
idUDPClient1.Host:=Edit2.Text;
idUDPClient1.Port:=StrtoInt(Edit3.text);
idUDPClient1.SendBuffer(msg,sizeof(msg));
end
else
messagedlg('是不是漏了点什么?',mtInformation,[mbOK],0);
end;
 
改用Delphi的UdpSocket试试,他就没有此问题
 
后退
顶部