TIdUDPServer.Active:=true;错误后的异常处理

独醒子 2011-01-20 09:55:50
刚发个帖子没人回 再发一贴

程序设置一个数组aryPort[0..9],存放了10个端口号。
程序一开始做个循环,找到第一个没被使用的端口号使用。
也就是在循环内设置下一个端口号并且打开,当失败后继续试下一个。
udp:TIdUDPServer控件

procedure TfrmMain.FormCreate(Sender: TObject);
var i:Integer;
begin
for i:=0 to 9 do
begin
try
udp.Active:=true;
if udp.Active=true then break;
except
end;
end;
end;

就程序开始这么几句话,非常简单。但是出现问题。
如果第一个端口号未被使用,程序会打开此端口开始监听。
若端口被占用,即 udp.Active:=true; 语句出错抛出异常。
主程序窗口会显示,但循环停止了。
我该如何处理此类事情呢?
请高手指点

ps:我程序是服务端也是客户端,当然有原因不能使用固定端口号。
请指教 谢谢 在线等待。
...全文
168 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
BCBPLC 2011-01-22
  • 打赏
  • 举报
回复
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Udp1->Active=false;
Udp1->Bindings->Clear(); // 这样,我的毛病就消失了,松绑!
Udp1->DefaultPort=Port0->Text.ToInt();
Udp1->Active=true;
}
BCBPLC 2011-01-22
  • 打赏
  • 举报
回复
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Udp1->Active=false; // 关旧端口
Udp1->DefaultPort=Port0->Text.ToInt(); //新端口
Udp1->Active=true; // 这已没法通讯了
}
BCBPLC 2011-01-22
  • 打赏
  • 举报
回复
楼主对这UDP控件的特性可能还不十分了解。
我这次编串行通迅与UDP通迅,用了多端口,
发现UDP的两个第三方控件都有些问题,这个
TIdUDPServer有个问题,它的->Active
一旦从true改成false,以便改端口,这个控件
就没法再通迅了。不知为什么。我只要改用
TNMUDP了,
hongqi162 2011-01-21
  • 打赏
  • 举报
回复
function OpenPort(port: Integer):boolean;
begin
try
udp.DefaultPort:= port;
udp.Active:=true;
udp.Active:= false;
result:= true;
except
result:= false;
end;
end;
独醒子 2011-01-21
  • 打赏
  • 举报
回复
我知道原因了,我将程序改了。测试的时候create一个新的TidUdpServer就可以了
代码改为:
function TfrmMain.openPort(iPort:Integer):boolean;
var tmpUdp:TIdUDPServer;
begin
tmpUdp:=TIdUDPServer.Create(nil);
try
tmpUdp.DefaultPort:= iPort;
tmpUdp.Active:=true;
tmpUdp.Active:= false;
result:= true;
except
result:= false;
end;
freeandnil(tmpUdp);
end;
====================================
这么看 原因在这个控件本身,
修改端口的语句并没有成功,端口号只有第一次赋值是成功的。
真是闷~~~
独醒子 2011-01-21
  • 打赏
  • 举报
回复
刚才又写了2个测试程序 可能发现了问题原因了。
我的列表里有10个端口 比如是1-10

-------情况1-----------
程序1不执行
程序2循环测试打开端口1-10,提示10次成功

-------情况2-----------
程序1打开端口1 执行成功
程序2循环测试打开端口1-10,提示了10次端口已被占用

-------情况3-----------
程序1打开端口5 执行成功
程序2循环测试打开端口1-10,提示10次成功信息

请高手帮忙看看,貌似循环测试的时候端口号根本没有变
可我跟踪程序查看端口属性值的确每次都在变
同时txMsg.Text:=inttostr(udpS.DefaultPort)+#13+#10+txMsg.Text;
的确也显示了不同的端口号
咋只要第一次测试端口被占用 就10次全被占用
而第一次测试没被占用,无论后面几次是否被占用,10次测试都提示被占用。

望高手解决 谢谢了
独醒子 2011-01-21
  • 打赏
  • 举报
回复
你的代码没有问题啦,但是还是不行,这样吧 我粘贴我的代码好了

===========unit unFrmMain;==============
procedure TfrmMain.FormCreate(Sender: TObject);
var i,k:Integer;
begin
adObj:=TADObj.Create;
for i:=0 to adObj.defPortCount-1 do
begin
k:=adobj.GetDefPort;
txMsg.Text:='test port:'+inttostr(k)+#13+#10+txMsg.Text;
if openPort(k) then
begin
txMsg.Text:='==OK=='+inttostr(udpS.DefaultPort)+#13+#10+txMsg.Text;
udpS.Active:=true;
break;
end;
end;
end;

function TfrmMain.openPort(iPort:Integer):boolean;
begin
try
udpS.DefaultPort:= iPort;
udpS.Active:=true;
udpS.Active:= false;
result:= true;
except
result:= false;
end;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
udpS.Active:=false;
end;


=========unit unADObj;================

const
cPortListCount = 10;
cPortList :array [0..9] of Integer = (8500,8600,8700,8900,9100,9200,9300,9400,9500,8800);


type
TADObj=class
private
//
public
nowIPid,defPort,defPortCount:Integer;
constructor Create;
destructor Destroy; override;
function GetDefPort():Integer;
end;

constructor TADObj.Create;
begin
self.nowIPid:=0;
defPortCount:=cPortListCount;
end;

function TADObj.GetDefPort():Integer;
var idef:Integer;
begin
idef:= GetPort(self.nowIPid); //此函数获得一个端口号,端口号是根据硬盘序列号随机算一个数值,然后从端口列表cPortList 中对应位置取出,即每台机器执行时首次取的端口号可能不一样
if self.nowIPid=0 then defPort:=idef;
self.nowIPid:=self.nowIPid+1;
Result:= idef;
end;

========================================
测试是这样测试的。首先程序执行一次没问题。
将exe文件复制一个副本 执行副本
副本执行成功:txMsg文本提示信息如下:
====================
0==OK==9300
test port:9300
=====================
复制的副本程序不关闭,同时delphi也调试程序
提示一个错误信息:
EIdCouldNotBindSocket
'Could not bind socket. Address and port are already in use'
这样的错误提示显示了10次
txMsg文本内信息如下:
====================
test port:9200
test port:9100
test port:8900
test port:8700
test port:8600
test port:8500
test port:8800
test port:9500
test port:9400
test port:9300
======================
我调试进程序,发现每次udpS.DefaultPort:= iPort;语句执行都是对的
端口值每次也成功更换,但是链接就是提示端口已经被占用的错误信息,
请问这是咋回事啊?

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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