现在有个Delphi写的CGI程序,当有2个客户端调用时,就死机,并且web services 的CPU占用率一直为100%,有什么办法可以改变吗?

解决方案 »

  1.   

    代码如下:
    unit ZipFileImpl;interfaceuses InvokeRegistry, Types, XSBuiltIns, ZipFileIntf,Classes,sysutils,Forms,windows;type  { TZipFile }
      TZipFile = class(TInvokableClass, IZipFile)
      public
          {外部输出函数}
         function SaveFileToServer(Const ClientIp,ZipFileStr,cFileName,sFilePath:String;
                                         SendCount:Integer;IsLast:Boolean):Integer;Stdcall;
                                                                             //保存客户端文件到服务器中
         function GetString:String;stdcall;     {内部使用函数}
      
         function  XTToUnCompressSoapPacket(Const spPacket :String):String;  //客户端收到web Service传来的文件进行解压                                                       }
         function  WriteTempFile(TempStr,TempFile:String):Boolean;
         function  ReadTempFile(FileName,FilePath,ClientIp:String;FileNum:Integer):Boolean;
         function  MyDeleteTree(SourceName:String): Boolean;
      end;implementation
       uses Zlib,ShellApI, EncdDecd;function TZipFile.XTToUnCompressSoapPacket(Const spPacket :String):String;
    var
      msData,msEncoded   :TMemoryStream;
      zLibUnCompressor   :TDecompressionStream;
      fBufLen            :Integer;
      fBuffer            :array [0..16383] of byte;
    begin
       msData    :=TMemoryStream.Create;
       msEncoded :=TMemoryStream.Create;
       Try
          msData.Size :=Length(spPacket);
          move(spPacket[1],msData.Memory^,msdata.size);
          msData.Position :=0; DecodeStream(msData ,msEncoded);
          msData.Size :=0;
          msEncoded.Position :=0;
          zlibUnCompressor :=TDeCompressionStream.Create(msEncoded);
          try
             fBufLen :=zLibUnCompressor.Read(fBuffer,SizeOf(fBuffer));
             while fBuflen >0 do
             begin
                msData.write(fBuffer, fBuflen);
    fBuflen :=zLibUnCompressor.Read(fBuffer,SizeOf(fBuffer));
             end;
          finally
     FreeAndNil(zLibUnCompressor);
     zLibUnCompressor.Free;
          end; msData.Position :=0;
          SetLength(Result,msData.size);
          move(msData.memory^,Result[1],MsData.Size);
       finally
    FreeAndNil(msEncoded);
    FreeAndNil(msData);
    msEncoded.Free;
    msData.Free;
       end;
    end;
    {保存客户端文件到服务端}
    function TZipFile.SaveFileToServer(Const ClientIp,ZipFileStr,cFileName,sFilePath:String;
    SendCount:Integer;IsLast:Boolean):Integer;Stdcall;
    var
      UnZipStrFile:String;
      TempFileName:String;
    TmpZipStr   :String;
    i,m :integer;
    begin
     sleep(0);
     try
     UnZipStrFile:=XTToUnCompressSoapPacket(ZipFileStr); //解压后文件
       except
         Result:=-1;
     Exit;
     end; 
       if IsLast then //最后一个文件
       begin      TempFileName:=sFilePath+'Temp\'+ClientIp+'\'+IntToStr(SendCount);
          WriteTempFile(UnZipStrFile,TempFileName);      if ReadTempFile(cFileName,sFilePath,ClientIp,SendCount) then
          begin
             Result:=0;
             Exit;
          end;
       end
       else
       begin
          if SendCount=1 then   
          begin
     try
             if DirectoryExists(sFilePath+'Temp\'+ClientIp) then
                   MyDeleteTree(sFilePath+'Temp\'+ClientIp);
             except
                Result:=100;
                Exit;
             end;         if not DirectoryExists(sFilePath+'Temp\')  then
             try
                MkDir(sFilePath+'Temp\');
             except
                Result:=200;
                Exit;
             end;
             if not DirectoryExists(sFilePath+'Temp\'+ClientIp)  then
             try
                MkDir(sFilePath+'Temp\'+ClientIp);
             except
                Result:=300;
                Exit;
             end;
          end;      
          TempFileName:=sFilePath+'Temp\'+ClientIp+'\'+IntToStr(SendCount);
          try
            WriteTempFile(UnZipStrFile,TempFileName);
          except
            Result:=400;
            Exit;
    end;
     end; 
       Result:=0;
    end;
    function TZipFile.WriteTempFile(TempStr,TempFile:String):Boolean;
    var
      fs : TFileStream;
    begin
       fs:=TFileStream.Create(TempFile,fmCreate);
       try
          fs.Write(TempStr[1],Length(TempStr));
       finally
          fs.free;
       end;//
    end;function TZipFile.ReadTempFile(FileName,FilePath,ClientIp:String;FileNum:Integer):Boolean;
    var
      OrdFile,SourceFile : TFileStream;
      i:integer;
      TmpName:String;
    begin
      OrdFile := TFileStream.Create(FilePath+FileName, fmCreate  or fmShareDenyWrite);
      try
        for i:=1 to FileNum do
        begin
          TmpName:=FilePath+'Temp\'+ClientIp+'\'+IntToStr(i);
          SourceFile := TFileStream.Create(TmpName, fmOpenRead or fmShareDenyWrite);
          try
            OrdFile.CopyFrom(SourceFile, 0);
          finally
            SourceFile.Free;
          end;
        end;  finally
        OrdFile.Free;
      end;end;function TZipFile.MyDeleteTree(SourceName:String): Boolean;
    var
      F:TShFileOpStruct;
    begin
      F.wnd:=0;
      F.wFunc:=FO_DELETE; {操作方式}
      F.pFrom:=PChar(SourceName +#0#0);
    F.pTo:=PChar(''+#0#0);
      F.fFlags:=FOF_SILENT or FOF_NOCONFIRMATION;
    result:= ShFileOperation(F)=0;
    end;function TZipFile.GetString: String;
    begin   try
    MyDeleteTree('D:\DownLoad\Temp\10.42.27.200');
       except
    Result :='你好,这里是CGI服务中心!删除文件夹 D:\DownLoad\Temp\10.42.27.200 失败!';
          Exit;
       end;   try
         if  not DirectoryExists('D:\DownLoad\Temp') then
             MkDir('D:\DownLoad\Temp');
     if  not  DirectoryExists('D:\DownLoad\Temp\10.42.27.200') then
     MkDir('D:\DownLoad\Temp\10.42.27.200');
       except
    Result :='你好,这里是CGI服务中心!创建文件夹 D:\DownLoad\Temp\10.42.27.200 失败!';
          Exit;
       end;  Result :='删除与建立文件夹10.42.27.200都成功!';end;initialization
      { Invokable classes must be registered }
      InvRegistry.RegisterInvokableClass(TZipFile);end.由于需要频繁调用函数传输文件,CPU占用率很高,并且容易死机.
      

  2.   

    怎么不是CGI呢?通过Delphi-->File--->web Services---->Soap Server Application ,选择CGI模式编写出来的啊,编译成.exe 文件啊.
      

  3.   

    Isapi行不行?另外两个人同时操作一个目录同一个文件?能行么?估计需要做一个保护把
      

  4.   

    后来我将函数 SaveFileToServer 内的代码全部注释掉,只返回成功信息 Result:=0 ,在客户端同时调用时,还是占用CPU100%,并且在连续调用几百次后,服务器死机或蓝屏....到底Delphi用此方式写的CGI可不可以用,困惑啊
      

  5.   

    你的是WebService服务程序,不是普通的CGI!
    CGI是使用:New-Web Server Application建立的框架如下:unit Unit1;interfaceuses
      SysUtils, Classes, HTTPApp;type
      TWebModule1 = class(TWebModule)
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      WebModule1: TWebModule1;implementation{$R *.dfm}end.另外WS服务的调用方法也是不同的,找书看看吧,简单说就是相当于写一个DLL,把这个DLL做在Web服务器上给远程客户调用
    _____________________
    http://lysoft.7u7.net
      

  6.   

    做什么CGI 咯;wincgi是最差的;还比不上perl写的,delphi可以编译为exe(CGI 模式)和dll(ISAPI)模式,iis下最快的就是isapi ,但是属于服务进程内,如果有指针错误或者程序bug,会让iis死掉!cgi 则只是进程模式运行,如果你的cgi被启动后,那么分配给每个session都是独立的进程,一台服务器运行你的cgi不过几百几千个,如果你的cgi程序做的又大又消耗内存,服务器运行几个连接后cpu 100%是很正常的;你还是重新设计你的东西,如果坚持做将得不偿失,你做的那玩意还不如asp的脚本。
      

  7.   

    你干脆写成comobj ,随时可调用;
    还有,你得有加锁的概念,就和数据库的加锁一个意思;在传统cgi的实现有很多办法,比如到磁盘上写个xxx.lock 文件,在进程2的时候检查文件是否存在,存在则sleep(...);只到文件消失后再建立这样的标记文件。