TTcpServer控件是D7才加入的控件,Borland已经不建议用户使用旧的TClientSocket和TServerSocket了。
TTcpServer有三种模式bmBlocking/bmNonBlocking/bmThreadBlocking.
目前我是用bmThreadBlocking模式由TTcpServer自动为每个连接分配线程,但是问题在于当每个连接建立的时候TTcpServer的OnAccept事件会正常触发,在这个事件的内部也可以收发数据,但是只要这个事件返回,这个连接就会被释放了。这样每次在Client端发送数据都要重连一次。请问高手这是怎么回事,如何才能很好的控制TTcpServer。另外,两种模式我没试过,似乎和Windows Socket API使用很象,有哪位大哥知道的话,也希望能够不吝赐教。TTcpServer这方面的书实在太少了?Delphi自带的例子也太简单,刚好是连接,执行一次收发,然后结束,所以没有任何价值。

解决方案 »

  1.   

    稍微浏览过TTcpServer/TTcpClient的原代码, 发觉这好象是个未完工的东西, 作为自己写socket控件的基础类继承下来也许不错, 但是直接使用有很多问题, 反正borland推荐使用的是Indy. 不过我对Indy一向不大感冒. 我过去用过Indy的前一代: WinShoe, 写个支持50个左右连接的服务程序差点没被累死, 莫名其妙的死机, 连接失去响应等情况太多了, 还找不到原因. 最后实在没办法了不得不写了个守护程序监控服务端程序, 定时发发消息, 连连端口看看它是不是还活着, 如果死了就杀进程然后重新运行它. 用D7后瞄过一眼Indy的原代码发觉其底层和WinShoe相比没有什么改动, 所以除了写过几个测试程序外也就没用过Indy(也不敢用了--典型的一朝被蛇咬啊). 最后发觉还是TServerSocket和TClientSocket最好用. 虽然它的效率很成问题.所以现在我用的都是我自己用api写的.
      

  2.   


    必须用线程;
    1. tcpclient从tcpserver接收数据:  TReceiveThread = class(TThread)
      private
        FMsg: string;
      protected
        procedure Execute; override;
      end;var
      FThread: TReceiveThread;
    procedure TReceiveThread.Execute;
    begin
      while not Terminated do
      begin
        if Form1.IdTCPClient1.Connected then
        begin
          FMsg := Form1.IdTCPClient1.ReadLn;
          Sleep(100);
        end;
      end;
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      FThread := TReceiveThread.Create(False);
      IdTCPClient1.Host := Edit1.Text;
      IdTCPClient1.Port := 10001;
      if not IdTCPClient1.Connected then
        IdTCPClient1.Connect;
    end;2. tcpserver向tcpclient发送数据
    procedure TForm1.SpeedButton1Click(Sender: TObject);
    var
      i : Integer;
      AThread : TIdPeerThread;
    begin
      try
        with IdTCPServer1.Threads.LockList do
        for I := 0 to Count - 1 do
        begin
          AThread := Items[I];
          if AThread.Connection.Socket.Binding.PeerIP = 'hostname' then
            AThread.Connection.WriteLn(s);
        end;
      finally
        IdTCPServer1.Threads.UnlockList;
      end;
    end;
      

  3.   


      放弃TTcpServer/TTcpClient  使用 TIdTcpServer 与 TIDTcpClient
      

  4.   

    server 端采用消息得异步模式只会让程序显得简单,但server端处理任务会影响数据得收发,并且根据事件编写代码会让代码过于分散了不利于维护,还是使用ThreadBlocking,这样得在线程函数之中编码会很清晰;你可以用TIDTcpServer改掉你原来得代码,只需要将代码改到execute 事件内,用状态机得机制来处理请求;而client 则用线程封装tIdTCPCLient,使用indy时千万不要使用TIdAntiFreeze,这个东西其实只是application.ProcessMessages,版本可以采用delphi7自己带得,我最近用了indy10,TidUdpserver有点bug,处理同步请求,udpclient 读取缓冲,会有指针错误,tcpserver则没有这些问题,我是到做一个视频聊天得程序,得到这些简单得经验,希望能对楼主有用。
      

  5.   

    QWERT520(别来无恙),pbtlightcs() , Bluce4587(老狼)讲的都是Indy的TIdTcpServer/TIdTcpClient,不是我要的答案,不过还是谢谢了。
        关于TTcpServer的使用我也看了一下源代码,不过Borland带的也只是部分,只能从概念上理解。希望能看到更细致的描述和经验,我个人觉得这两个组件发挥的空间还是蛮大的,只是没有使用什么的经验。
      

  6.   

    bmBlocking/bmNonBlocking/bmThreadBlocking
    已经说明了啊~
    不过s端一定要用threadblocking~=========
    稍微浏览过TTcpServer/TTcpClient的原代码, 发觉这好象是个未完工的东西, 作为自己写socket控件的基础类继承下来也许不错, 但是直接使用有很多问题, 反正borland推荐使用的是Indy. 
    =========瞎扯蛋~
    两者只是用的SELECT I/O模式而已,而且写的很好~
    对无需长连接,只要处理完毕数据即返回的请求,用这两组组件是效率最好的!
    要其他I/O模式的可自己写~原来D6的Sokcet组件就是消息IO~想用自己添加近来就好(我想有很多人用api写可能还没它好~)扯远了~
    正确做法是在OnGetThread接管线程自己实现数据请求
      

  7.   

    我也最近有这个问题?
    在ongetthread事件里面怎么下啊,
    比如客户端发送了一个消息,我要转发给其它客户端怎么做啊?
      

  8.   

    cd_fsy2000(神州行) ( ) 信誉:86  2005-11-01 11:09:00  得分: 0  
     
     
       我也最近有这个问题?
    在ongetthread事件里面怎么下啊,
    比如客户端发送了一个消息,我要转发给其它客户端怎么做啊?
      
     
    這也是我一直想問的問題﹐有沒有高手講一下啊?
      

  9.   

    自己直接用SOCKET写好了,写个自己够用的就行了,简单的收发也不难,而且效率还很高