我用TsocketServer做了一个socket服务程序,采用的是线程阻塞模式,这个程序的功能是接收客户端的socket信息,然后根据信息进行相应的处理,把处理结果返回给客户端。客户端少的情况下一切正常。为了测试这个服务器程序的性能,又做了一个测试程序,同时起几十个客户端,然后每个客户端不停的向服务器发送socket信息请求处理,这时问题就出来了,服务器程序中有些线程响应很快,但有个别线程响应的时间非常慢,客户端过很长时间才能收到服务器的处理结果,甚至根本收不到。如果逐渐手工结束一些客户端,减少到一定的程度,原先没有响应的客户端就能收到返回结果了。给我的感觉是当有客户端连接时服务器中分配一个线程的优先级不一样,那些响应慢的线程得不到足够的cpu时间,导致处理信息非常慢。但事实上服务器端起的每个线程优先级都一样(normal)。恳求各位大哥指点,该怎么样解决这个问题,我的程序要求时同时起几十个客户端然后不停的发信息给服务器,每一个客户端都能收到返回结果。收到结果的间隔时间肯定和客户端的连接数有关,间隔时间稍微长点没关系,但主要时确保每个客户端都能收到处理结果。

解决方案 »

  1.   

    参考VCL Source当中的scktsvr.dpr
      

  2.   

    做服务建议使用IOCP,网上有IOCP的Delphi控件Source.
      

  3.   

    谢谢unsigned(僵哥--只求一个瓜,不管酸甜苦辣,栽种心田,不管海角) ,我去年做的一个三层结构的东西就是你提供的easydcom的方式做的。但现在公司要我自己做一个SocketServer。
      

  4.   

    以前一直都是用vb的,delphi才搞了不到一个月,这个问题有点棘手。
      

  5.   

    程序中的主要代码如下:
    Procedure TForm1.ServerSocket1GetThread(Sender: TObject;
      ClientSocket: TServerClientWinSocket;
      Var SocketThread: TServerClientThread);
    Begin
      // Create a new thread for connection
     SocketThread := TMyServerThread.Create(false, ClientSocket);End;Procedure TMyServerThread.ClientExecute;
    Var
      Data: Array[0..2047] Of char;
      RecText: String;
      SocketStream: TWinSocketStream;
    Begin
      While Not Terminated And ClientSocket.Connected Do
      Try
        SocketStream := TWinSocketStream.Create(ClientSocket, 15000);
        Try
          FillChar(Data, SizeOf(Data), 0);
          If SocketStream.Read(Data, SizeOf(Data)) = 0 Then
          Begin
            sleep(100);
          End;
          RecText:= Data;
          If ClientSocket.Connected Then
          Begin
            if RecText<>'' then
              begin
                sleep(10);
                ProcessData(RecText); //处理信息函数
              end
            else
               //尝试发送数据,检测客户端是否连接着
              ClientSocket.SendText(#10)
          End;
        Finally
          SocketStream.Free;
         End;
      Except
        on ESocketError do
        begin
        //showmessage(' socket err');
         ClientSocket.close;
        Terminate;
        end;
      End;
    End;请高手帮忙诊断一下!
      

  6.   

    对于使用多线程阻塞模式,不如直接使用API自己封装一个类,更灵活,TSocketServer类,是一个比较傻瓜化的,当中还是有相当的问题,我个人不太建议使用。即便是BDS2006当中的TTCPServer我也不太喜欢,稍看了一下Source,感觉还是自己全新封装比较放心点,并且这个封装也不是太麻烦。上面的代码,其它的我没发现什么问题,不过这是一个线程函数,在下面的语句调用时须考虑使用同步ProcessData(RecText); //处理信息函数否则如果在ProcessData当中涉及主线程 VCL的访问,多个线程之间就有可能发生资源冲突
      

  7.   

    Suggest using none blocking mode, Windows will be blocked in some conditions if using Blocking mode, but use threads to process readed data.
      

  8.   

    block mode 我也试过了,当客户端多的时候而且有客户端不停的发数据时会有客户端连不上的情况。