各位大虾,有谁知道如何处理TServerClientWinSocket类的OnErrorEvent事件,急急急,在线等待,分不够可以加

解决方案 »

  1.   

    我写了一个多线程socket服务器接收图片的程序,可是当有大量图片上传,且网络突然中断的情况就是报系统错误并且主程序关闭,我要解决的问题就是如何正确处理这些系统错误:
    我的线程代码如下:
    type
    TClientThread = Class(TServerClientThread)
      private
      public
        filename: string;
        filelen: Longint;
        DestStream: TMemoryStream;
        intError :integer;
        procedure ClientExecute; override;
        procedure UnCompressBitmap(const CompressedStream: TMemoryStream);
        procedure show;
        procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
        procedure errorCount;
      end;
      ReceiptImage =record
        thd      :TClientThread;
        blStatus :boolean;
      end;const  C_Client_CanBegin   = '111111';  //开始发送请求
      C_Client_END        = '222222';  //发送完毕
      C_Client_FileLenth  = '333333';  //文件的长度  C_Server_Begin      = '444444';  //回复,可以发送了
      C_Server_NextData   = '555555';  //下一个文件数据包
      C_Server_NeedData   = '666666';  //服务器叫客户端送文件上来
    implementation{$R *.dfm}procedure TClientThread.ClientExecute;
    var
      stmp: string;
      tmp : string;
      ilength: integer;
      Buffer: pointer;
      size: integer;  SocketStream : TWinSocketStream;
      ReceiveBuffer : Array[0..1025] Of Char;
      BytesRead : Integer;
      iniFile : TIniFile;
    begin try
     FreeOnTerminate :=true;
     ClientSocket.SendText(C_Server_NeedData);
     ClientSocket.OnErrorEvent :=doException;
     while not Terminated and ClientSocket.Connected do
      Begin
       try
            SocketStream := TWinSocketStream.Create(ClientSocket, 5000);
            try
                    FillChar(ReceiveBuffer, sizeof(ReceiveBuffer), 0);
                    if SocketStream.WaitForData(5000) then
                    begin
                            if Assigned(SocketStream) then
                            begin
                                    intError :=0;
                                    try
                                            BytesRead := SocketStream.Read(ReceiveBuffer,SizeOf(ReceiveBuffer));
                                    except
                                            ClientSocket.Close;
                                    end;
                                    if BytesRead = 0 then
                                    begin
                                            ClientSocket.Close;
                                    end
                                    else
                                    begin
                                            tmp:=ReceiveBuffer;
                                            stmp := copy(tmp ,1,6);
                                            if stmp = C_Client_CanBegin then     //如果收到请求回复以下
                                            begin
                                                    filename := copy(tmp,7,BytesRead-6);
                                                    ClientSocket.SendText (C_Server_Begin);
                                            end
                                            else if stmp = C_Client_FileLenth then   //收到文件的长度
                                            begin
                                                    DestStream := TMemoryStream.Create;
                                                    filelen := strtoint(copy(tmp,7,BytesRead-6));
                                                    ClientSocket.SendText(C_Server_NextData); //开始接收数据
                                            end
                                            else if stmp = C_Client_End then     //如果数据发送完毕
                                            begin
                                                    DestStream.Position := 0;
                                                    UnCompressBitmap(DestStream);
                                                    DestStream.Free;
                                                    ClientSocket.Close;
                                                    Synchronize(show);
                                            end
                                            else
                                            begin
                                                    DestStream.WriteBuffer(ReceiveBuffer,BytesRead);//
                                                    ClientSocket.SendText(C_Server_NextData);                                        end;
                                    end;
                            end;
                    end
                    else
                    begin
                            //如果连续5次没有收到数据,则认为永远收不到数据。关闭连接
                            if intError>5 then
                            begin
                                    ClientSocket.Close;
                            end
                            else
                            begin
                                    inc(intError);
                            end;
                    end;
            finally
                    freeAndNil(SocketStream);
            end;
         except
            //FreeMem(Buffer,iLength);
            if Assigned(SocketStream) then  SocketStream.Free;
            if ClientSocket.Connected then  ClientSocket.Close;
         end;
     end;
     except
            if ClientSocket.Connected then  ClientSocket.Close;
            ClientSocket.Free;
     end;
    end;procedure TClientThread.UnCompressBitmap(const CompressedStream: TMemoryStream);
    const
      ImagePath = 'SoftWare\NetBar\WebApp\';
    var
      SourceStream: TDecompressionStream;
      DestStream: TMemoryStream;
      Buffer: PChar;
      Count: LongInt;
      Path: string;
      iniFile :TIniFile;
    Begin
      try
            getmem(buffer,filelen);
            DestStream := TMemoryStream.Create;
            SourceStream := TDecompressionStream.Create(CompressedStream);
            Try
                    SourceStream.ReadBuffer(Buffer^, filelen);
                    DestStream.WriteBuffer(Buffer^, filelen);
                    DestStream.Position := 0;//复位流指针
                    Path := ExtractFilePath(application.ExeName);
                    if not directoryexists(Path) then createdirectory(pchar(Path),0);
                    DestStream.SaveToFile (Path +'\pic\'+filename+'.jpg');
            finally
                    FreeMem(Buffer);
                    freeAndNil(DestStream);
                    freeAndNil(SourceStream);
            end;
      except
            if Assigned(Buffer) then FreeMem(Buffer);
            if Assigned(DestStream) then DestStream.Free;
      end;
    end;
    procedure TClientThread.errorCount;
    begin
            form1.Memo2.Lines.Append(fileName);
    end;procedure TClientThread.doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    begin
            //这段代码有问题
            Socket.Close;
            Socket.Free;  
    end;
      

  2.   

    我整理重发一下以上我的原代码:
    我写了一个多线程socket服务器接收图片的程序,可是当有大量图片上传,且网络突然中断的情况就是报系统错误并且主程序关闭,我要解决的问题就是如何正确处理这些系统错误,我认为主要要解决的问题就是正确处理过程procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);:
    我的线程代码如下:
    type
    TClientThread = Class(TServerClientThread)
      private
      public
        filename: string;
        filelen: Longint;
        DestStream: TMemoryStream;
        intError :integer;
        procedure ClientExecute; override;
        procedure UnCompressBitmap(const CompressedStream: TMemoryStream);
        procedure show;
        procedure doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
        procedure errorCount;
      end;
      ReceiptImage =record
        thd      :TClientThread;
        blStatus :boolean;
      end;const  C_Client_CanBegin   = '111111';  //开始发送请求
      C_Client_END        = '222222';  //发送完毕
      C_Client_FileLenth  = '333333';  //文件的长度  C_Server_Begin      = '444444';  //回复,可以发送了
      C_Server_NextData   = '555555';  //下一个文件数据包
      C_Server_NeedData   = '666666';  //服务器叫客户端送文件上来
    implementation{$R *.dfm}procedure TClientThread.ClientExecute;
    var
      stmp: string;
      tmp : string;
      ilength: integer;
      Buffer: pointer;
      size: integer;  SocketStream : TWinSocketStream;
      ReceiveBuffer : Array[0..1025] Of Char;
      BytesRead : Integer;
      iniFile : TIniFile;
    begin try
     FreeOnTerminate :=true;
     ClientSocket.SendText(C_Server_NeedData);
     ClientSocket.OnErrorEvent :=doException;
     while not Terminated and ClientSocket.Connected do
      Begin
       try
         SocketStream := TWinSocketStream.Create(ClientSocket, 5000);
         try
           FillChar(ReceiveBuffer, sizeof(ReceiveBuffer), 0);
           if SocketStream.WaitForData(5000) then
           begin
             if Assigned(SocketStream) then
             begin
               intError :=0;
               try
                 BytesRead := SocketStream.Read(ReceiveBuffer,SizeOf(ReceiveBuffer));
                 except
                   ClientSocket.Close;
                 end;
                 if BytesRead = 0 then
                 begin
                   ClientSocket.Close;
                 end
                 else
                 begin
                   tmp:=ReceiveBuffer;
                   stmp := copy(tmp ,1,6);
                   if stmp = C_Client_CanBegin then     //如果收到请求回复以下
                   begin
                     filename := copy(tmp,7,BytesRead-6);
                     ClientSocket.SendText (C_Server_Begin);
                   end
                   else if stmp = C_Client_FileLenth then   //收到文件的长度
                   begin
                      DestStream := TMemoryStream.Create;
                      filelen := strtoint(copy(tmp,7,BytesRead-6));
                      ClientSocket.SendText(C_Server_NextData); //开始接收数据
                   end
                      else if stmp = C_Client_End then     //如果数据发送完毕
                   begin
                      DestStream.Position := 0;
                      UnCompressBitmap(DestStream);
                      DestStream.Free;
                      ClientSocket.Close;
                   end
                   else
                   begin
                     DestStream.WriteBuffer(ReceiveBuffer,BytesRead);//
                     ClientSocket.SendText(C_Server_NextData);               end;
                 end;
               end;
             end
             else
             begin
               //如果连续5次没有收到数据,则认为永远收不到数据。关闭连接
               if intError>5 then
               begin
                 ClientSocket.Close;
               end
               else
               begin
                 inc(intError);
               end;
             end;
           finally
              freeAndNil(SocketStream);
           end;
         except
            //FreeMem(Buffer,iLength);
            if Assigned(SocketStream) then  SocketStream.Free;
            if ClientSocket.Connected then  ClientSocket.Close;
         end;
     end;
     except
            if ClientSocket.Connected then  ClientSocket.Close;
            ClientSocket.Free;
     end;
    end;procedure TClientThread.UnCompressBitmap(const CompressedStream: TMemoryStream);
    const
      ImagePath = 'SoftWare\NetBar\WebApp\';
    var
      SourceStream: TDecompressionStream;
      DestStream: TMemoryStream;
      Buffer: PChar;
      Count: LongInt;
      Path: string;
      iniFile :TIniFile;
    Begin
      try
            getmem(buffer,filelen);
            DestStream := TMemoryStream.Create;
            SourceStream := TDecompressionStream.Create(CompressedStream);
            Try
                    SourceStream.ReadBuffer(Buffer^, filelen);
                    DestStream.WriteBuffer(Buffer^, filelen);
                    DestStream.Position := 0;//复位流指针
                    Path := ExtractFilePath(application.ExeName);
                    if not directoryexists(Path) then createdirectory(pchar(Path),0);
                    DestStream.SaveToFile (Path +'\pic\'+filename+'.jpg');
            finally
                    FreeMem(Buffer);
                    freeAndNil(DestStream);
                    freeAndNil(SourceStream);
            end;
      except
            if Assigned(Buffer) then FreeMem(Buffer);
            if Assigned(DestStream) then DestStream.Free;
      end;
    end;
    procedure TClientThread.errorCount;
    begin
            form1.Memo2.Lines.Append(fileName);
    end;procedure TClientThread.doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    begin
            //这段代码有问题
            Socket.Close;
            Socket.Free;  
    end;
      

  3.   

    我看法同你不同。
    建议楼主先把所有的doException处理的代码删掉。。那些东西主要是为了非阻塞SOCKET设计的。首先看你工作线程里面基本上该抓的异常都已经抓了,这儿应该不会造成系统死掉。
    剩下一种可能就是你工作线程同主线程造成的冲突。。procedure TClientThread.errorCount;
    begin
            form1.Memo2.Lines.Append(fileName);
    end;
    这是典型的线程不安全的。。
    另外,对文件操作也可能资源冲突。。
      

  4.   

    我这个程序现在主要是报:Access violation at address 77F856A3 in module 'ntdll.dll'.Read of address FF14E4B0
      

  5.   

    delphi专区这是怎么了。
    没人讨论,郁闷
      

  6.   

    halfdream(哈欠)  非常认真的回答了你的问题,
    不过他只是说  "这是典型的线程不安全的。。"
    怎么不和他说线程同步呢?
      

  7.   

    procedure TClientThread.doException(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    begin
       case errorcode of
       //错误代码比如
       10004:
             begin
               showmeeesage('操作被中断');
               ErrorCode:=0
             end;
        
    end;