IdUDPClient和IdUDPServer实现最简单的功能,但还是有问题:Client和server都设了一样的端口,client设了server的IP,并且都active=true了
UDP的Client端有一定时器(每秒)读取收到的数据,如下:
procedure TForm1.Timer1Timer(Sender: TObject);
var
s:string;
begin
s:=IdUDPClient1.ReceiveString();
if s<>'' then
listbox1.Items.Add(s);
end;
UDP的server端有一按钮发送给client的数据:procedure TForm1.Button1Click(Sender: TObject);
begin
  IdUDPServer1.Send('192.100.100.121',9903,'abcd');
end;问题:
client收不到server的数据,而且定时器使程序变得很慢

解决方案 »

  1.   

    用IdUDPClient实现数据的发送,用IdUDPServer接收数据,当IdUDPClient发送数据后,IdUDPServer的OnUDPRead事件中就可以接收到你发送的数据,根本没必要用timer。 建议你找个IdUDPClient和IdUDPServer控件demo例子好好看看。
      

  2.   

    客户端:
    var
      cmd: string;
      ASize, TotalSize: Int64;
      AFileStream: TFileStream;
    begin
      IdTCPClient1.Host := Edit1.Text; //连接主机
      IdTCPClient1.Port := StrToIntDef(Edit2.Text, 9925); //端口
      IdTCPClient1.Connect; //连接
      try
        IdTCPClient1.WriteLn('BEGIN'); //提示服务器开始接收
        cmd := IdTCPClient1.ReadLn;
        //以“|”符号分离文件名
        SaveDialog1.FileName := Copy(cmd, Pos('|', cmd) + 1, Length(cmd));
        if not SaveDialog1.Execute then
        begin
          IdTCPClient1.WriteLn('CANCEL'); //告诉服务器取消
          IdTCPClient1.Disconnect; //断开连接
          exit;
        end;
        TotalSize := StrToInt(Copy(cmd, 0, Pos('|', cmd) - 1)); //分离文件大小
        //建立文件流准备接收
        AFileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate);
        try //循环开始接受
          repeat
            IdTCPClient1.WriteLn(IntToStr(AFileStream.Size));//发送当前传输的位置
            ASize := Min(TotalSize - AFileStream.Size, IdTCPClient1.RecvBufferSize);
            //选择剩余大小和缓冲区大小小的一个作为传输的大小
            IdTCPClient1.ReadStream(AFileStream, ASize); //接收流
            StatusBar1.SimpleText := Format('当前传输位置%d/大小%d', [AFileStream.Size, TotalSize]);
            Application.ProcessMessages;
          until AFileStream.Size = TotalSize; //大小一致了表示结束
        finally
          AFileStream.Free; //释放文件流
        end;
        IdTCPClient1.WriteLn('END'); //提示服务器传输完成
        StatusBar1.SimpleText := '传输完成...';
      except
        StatusBar1.SimpleText := '连接服务器失败或者对方已经中断传输!';
      end;
      IdTCPClient1.Disconne
      

  3.   

    服务器:
    procedure Tfrm_Server.IdTCPServer1Execute(AThread: TIdPeerThread);
    var
      cmd: string; //接收到客户端的字符串信息
      ASize: Integer; //需要传输的流大小
    begin
      with AThread.Connection do //已经连街上的一个进程
      begin
        cmd := UpperCase(ReadLn); //客户端发送的命令字符串
        if cmd = 'BEGIN' then //开始传输
        begin
          //告诉远程传输文件的大小和文件名
          WriteLn(Format('%d|%s', [AFileStream.Size, ExtractFileName(Edit1.Text)]));
          StatusBar1.SimpleText := '准备传输...';
          Exit;
        end;
        if cmd = 'END' then
        begin //传输完成
          Button3.Click;
          StatusBar1.SimpleText := '传输完成...';
          Exit;
        end;
        if cmd = 'CANCEL' then
        begin //传输取消
          StatusBar1.SimpleText := '传输取消...';
          //保持传输状态
          Exit;
        end;
        //按照指定位置传输文件
        AFileStream.Seek(StrToInT(cmd), soFromBeginning); //转到文件流传输的位置
        ASize := Min(AFileStream.Size - AFileStream.Position, RecvBufferSize);
        //计算需要发送的大小,Min()函数在Math单元
        OpenWriteBuffer; //准备发送缓冲
        WriteStream(AFileStream, false, false, ASize);
        //注意这个函数的参数。
        CloseWriteBuffer; //结束发送缓冲
        StatusBar1.SimpleText := Format('当前传输位置%s/大小%d', [cmd, AFileStream.Size]);
        ProgressBar1.Position := ProgressBar1.Position + ASize;
      end;
    end;
      

  4.   

     Simple UDP client demo Verified;
      Indy 9:
        D7: 25th Oct 2004 Andy Neillans
    }
    unit UDPClientMain;interfaceuses
      Windows, Messages, Graphics, Controls, Forms, Dialogs, IdWinsock2,   stdctrls,
      SysUtils, Classes, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze,
      IdComponent, IdUDPBase, IdUDPClient, IdStack;type
      TUDPMainForm = class(TForm)
        SourceGroupBox: TGroupBox;
        HostNameLabel: TLabel;
        HostAddressLabel: TLabel;
        HostName: TLabel;
        HostAddress: TLabel;
        UDPAntiFreeze: TIdAntiFreeze;
        PortLabel: TLabel;
        Port: TLabel;
        DestinationLabel: TLabel;
        DestinationAddress: TLabel;
        BufferSizeLabel: TLabel;
        BufferSize: TLabel;
        UDPMemo: TMemo;
        SendButton: TButton;
        UDPClient: TIdUDPClient;
        procedure FormCreate(Sender: TObject);
        procedure SendButtonClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      UDPMainForm: TUDPMainForm;implementationconst
      HOSTNAMELENGTH = 80;
      RECIEVETIMEOUT = 5000; // milliseconds{$R *.DFM}procedure TUDPMainForm.FormCreate(Sender: TObject);
    begin
      Randomize; // remove if you want reproducible results.
      HostName.Caption := UDPClient.LocalName;
      HostAddress.Caption := GStack.LocalAddress;
      Port.Caption := IntToStr(UDPClient.Port);
      DestinationAddress.Caption := UDPClient.Host;
      BufferSize.Caption := IntToStr(UDPClient.BufferSize);
      UDPClient.ReceiveTimeout := RECIEVETIMEOUT;
    end;procedure TUDPMainForm.SendButtonClick(Sender: TObject);
    var
      MessageID: Integer;
      ThisMessage: String;
      ReceivedString: String;
    begin
      MessageID := Random(MAXINT);
      ThisMessage := 'Message: ' + IntToStr(MessageID);
      UDPMemo.Lines.Add('Sending ' + ThisMessage);
      UDPClient.Send(ThisMessage);
      ReceivedString := UDPClient.ReceiveString();
      if ReceivedString = '' then
        UDPMemo.Lines.Add('No response received from the server after ' + IntToStr(UDPClient.ReceiveTimeout) + ' millseconds.')
      else
        UDPMemo.Lines.Add('Received: ' + ReceivedString)
    end;end.
      

  5.   

    Notes: Simple UDP server demoVerified:
      Indy 9:
        D7: 25th Oct 2004 Andy Neillans}unit UDPServerMain;interfaceuses
      Windows, Messages, Graphics, Controls, Forms, Dialogs, IdWinsock2, stdctrls,
      SysUtils, Classes, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze,
      IdComponent, IdUDPBase, IdUDPClient, IdStack, IdUDPServer, IdSocketHandle;
    type
      TUDPMainForm = class(TForm)
        SourceGroupBox: TGroupBox;
        HostNameLabel: TLabel;
        HostAddressLabel: TLabel;
        HostName: TLabel;
        HostAddress: TLabel;
        UDPServer: TIdUDPServer;
        UDPAntiFreeze: TIdAntiFreeze;
        PortLabel: TLabel;
        Port: TLabel;
        BufferSizeLabel: TLabel;
        BufferSize: TLabel;
        UDPMemo: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      UDPMainForm: TUDPMainForm;implementationconst
      HOSTNAMELENGTH = 80;{$R *.DFM}procedure TUDPMainForm.FormCreate(Sender: TObject);
    begin
      HostName.Caption := UDPServer.LocalName;
      HostAddress.Caption := GStack.LocalAddress;
      Port.Caption := IntToStr(UDPServer.DefaultPort);
      BufferSize.Caption := IntToStr(UDPServer.BufferSize);
      UDPServer.Active := True;
    end;procedure TUDPMainForm.UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
    var
      DataStringStream: TStringStream;
      s: String;
    begin
      DataStringStream := TStringStream.Create('');
      try
        DataStringStream.CopyFrom(AData, AData.Size);
        UDPMemo.Lines.Add('Received "' + DataStringStream.DataString + '" from ' + ABinding.PeerIP + ' on port ' + IntToStr(ABinding.PeerPort));
        s := 'Replied from ' + UDPServer.LocalName + ' to "' + DataStringStream.DataString + '"';
        ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));
      finally
        DataStringStream.Free;
      end;
    end;
    end.