我想做一个聊天室,经过考虑决定用TIdTCPClient和TIdTCPServer两个控件,服务器端使用起来还可以,可以客户端接收数据就成了问题,看了好多这方面的例子,基本上都是通过TTimes控件的OnTimer事件里写程序来读取接收到的数据的,我试着这样处理,可是客户端程序一运行就死在那里不动,不知是何原因?请教:1、如何正确使用TIdTCPClient控件读取接收到的数据?2、如果一定要用TTimes控件,请问有什么地方要注意的?怎样才能让客户端程序不死?3、希望能发一个好的例子给我([email protected])!多谢!!!!

解决方案 »

  1.   

    應該是你用了timer, 又用了阻塞方式通訊導致, 要麼, 寫到一個線程處理, 要麼不用阻塞式!
      

  2.   

    一般用线程处理吧。indy里的demo也是用timer的,结果就是不能正常运行。我估计可能是这个跟indy的阴塞机制有关。但并没有看到相关的文章说明。所以如果你用indy的话就用线程来接收吧。
      

  3.   

    用 IDtcpClient 怎样才能不用阻塞式?
      

  4.   

    用UDP挺方便,我有源程序,可以发一个给你.
      

  5.   

    谢谢!
    请发一个给我学习学习。
    [email protected]另外:如果规定用TCP实现怎么办?
      

  6.   


    事物都具有两面性,阻塞式Socket也不例外。它的一个主要的缺点就是使客户程序的用户界面“冻结”。当在程序的主线程中进行阻塞式Socket调用时,由于要等待Socket调用完成并返回,这段时间就不能处理用户界面消息,使得Update、Repaint以及其它消息得不到及时响应,从而导致用户界面被“冻结”。使用TIdAntiFreeze对抗“冻结”;
    这两天其实我自己也很郁闷。问题也没有解决。
    就是用IdTcPserver主动向在线的客户端发送消息。就像OICQ那样。没有解决阿。有知道的朋友吗?
      

  7.   

    --Client-----------------------------------------
    procedure TFormClient.btnGetFileClick(Sender: TObject);
    var
      stream: TStream;
    begin
      IdTCPClient1.WriteLn('getfile ' + HttpEncode (edFileName.Text));
      stream := TMemoryStream.Create;
      try
        IdTCPClient1.ReadStream(stream);
        stream.Position := 0;
        Image1.Picture.Bitmap.LoadFromStream (stream);
      finally
        stream.Free;
      end;
    end;--Server--------------------------------------object IdTCPServer1: TIdTCPServer
        Bindings = <>
        CommandHandlers = <      
          item
            CmdDelimiter = ' '
            Command = 'getfile'
            Disconnect = False
            Name = 'TIdCommandHandler2'
            OnCommand = IdTCPServer1TIdCommandHandler2Command
            ParamDelimiter = ' '
            ReplyExceptionCode = 0
            ReplyNormal.NumericCode = 0
            Tag = 0
          end>
        DefaultPort = 3000
        Greeting.NumericCode = 0
        MaxConnectionReply.NumericCode = 0
        MaxConnectionReply.Text.Strings = (
          'Already Full')
        OnConnect = IdTCPServer1Connect
        OnDisconnect = IdTCPServer1Disconnect
        ReplyExceptionCode = 0
        ReplyTexts = <>
        ReplyUnknownCommand.NumericCode = 0
        Left = 56
        Top = 24
      endprocedure TFormServer.IdTCPServer1TIdCommandHandler2Command(ASender: TIdCommand);
    var
      filename: string;
      fstream: TFileStream;
    begin
      if Assigned (ASender.Params) then
        filename := HttpDecode (ASender.Params[0]);
      if not FileExists (filename) then
      begin
        ASender.Response.Text := 'File not found';
        lbLog.Items.Add ('File not found: ' + filename);
        raise EIdTCPServerError.Create ('File not found: ' + filename);
      end
      else
      begin
        fstream := TFileStream.Create (filename, fmOpenRead);
        try
          ASender.Thread.Connection.WriteStream(fstream, True, True);
          // fStream.Size;
          lbLog.Items.Add ('File returned: ' + filename +
            ' (' + IntToStr (fStream.Size) + ')');
        finally
          fstream.Free;
        end;
      end;
    end;