刚发个帖子没人回 再发一贴程序设置一个数组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:我程序是服务端也是客户端,当然有原因不能使用固定端口号。
请指教 谢谢 在线等待。

解决方案 »

  1.   

    function OpenPort(port: Integer):boolean;
    begin
      try 
         udp.DefaultPort:= port;
         udp.Active:=true;
         udp.Active:= false;
         result:= true;
      except
         result:= false;
      end;
    end;
      

  2.   

    你的代码没有问题啦,但是还是不行,这样吧 我粘贴我的代码好了===========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;语句执行都是对的
    端口值每次也成功更换,但是链接就是提示端口已经被占用的错误信息,
    请问这是咋回事啊?
      

  3.   

    刚才又写了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次测试都提示被占用。望高手解决 谢谢了
      

  4.   

    我知道原因了,我将程序改了。测试的时候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;
    ====================================
    这么看 原因在这个控件本身,
    修改端口的语句并没有成功,端口号只有第一次赋值是成功的。
    真是闷~~~
      

  5.   

    楼主对这UDP控件的特性可能还不十分了解。
    我这次编串行通迅与UDP通迅,用了多端口,
    发现UDP的两个第三方控件都有些问题,这个
    TIdUDPServer有个问题,它的->Active
    一旦从true改成false,以便改端口,这个控件
    就没法再通迅了。不知为什么。我只要改用
    TNMUDP了, 
      

  6.   

    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
           Udp1->Active=false;                      // 关旧端口
           Udp1->DefaultPort=Port0->Text.ToInt();   //新端口
           Udp1->Active=true;                       // 这已没法通讯了
    }
      

  7.   

    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
           Udp1->Active=false;
           Udp1->Bindings->Clear();   // 这样,我的毛病就消失了,松绑!
           Udp1->DefaultPort=Port0->Text.ToInt();
           Udp1->Active=true;
    }