由于本人原来用的是vb中msWinsock.ocx控件,现在使用delphi,想继续使用msWinsock.ocx控件编程,问题如下:  
 
vb中的部分代码:  
 
Dim  DataPart()  As  Byte  
 
ReDim  DataPart(bytesTotal)  
sckData.GetData  DataPart,  vbByte  
Put  #filenumber,  Seek(filenumber),  DataPart  
 
请问以上代码在delphi中如何实现?并将接收到的数据保存到文件,非常感谢!

解决方案 »

  1.   

    早说过了,在Delphi当中对ActiveX控件支持不好,在Delphi当中有一大把控件可以使用,所以还是把mswinsock丢掉吧,Delphi当中有对网络API做封装,比如Indy控件TClientSocket/TServerSocket等,控制起来比MSWinsock要方便得多。
    比如上面的代码就可以写成:
    procedure TForm.ClientSocketRead(Sender: TObject;
      Socket: TCustomWinSocket);
    var
       DataPart:TMemoryStream;//内存流,也可以换作array of Byte;
       bytesTotal:Integer;    //当前收到数据的总长度
       bytesReceive:=Integer; //实际接收长度
    begin
       DataPart:=TMemoryStream.Create; //创建内存流对象实例
       try //使用try..finally以保证前面创建的内存流对象始终被释放
          bytesTotal:=Socket.ReceiveLength; //得到当前收到的数据总长度(单位:字节)
          DataPart.SetSize(bytesTotal); //分配空间
          //接收数据
          //DataPart.Memory:即前面分配空间的首地址
          //bytesTotal:预接收数量字节数
          //bytesReceive:实际收到的字节数
          bytesReceive:=Socket.ReceiveBuffer(DataPart.Memory,bytesTotal);
          //实际接收到的数据为小于0的数,表示未收到或者接收出错,返回
          if bytesReceive<=0 then Exit;
          //使用bytesTotal分配的是虚空间,故此需要置为实际空间大小,以便收回多余分配的空间
          DataPart.SetSize(bytesReceive);
          //将文件流指针置于尾部,以方便添加数据
          StreamFile.Seek(0,soEnd);//StreamFile:TFileStream,文件流对象
          //置内存流指针至首部,以在CopyFrom方法当中做正确数据的拷贝
          DataPart.Seek(0,soBeginning);
          //拷贝内存流当中的数据至文件尾,完成此次接收动作
          StreamFile.CopyFrom(DataPart,bytesReceive);
       finally
          DataPart.Free; //释放对象
       end;
    end;
      

  2.   

    没错,在Delphi当中对ActiveX控件支持是不好,但是我已经习惯用它了,能帮帮我吗?谢谢
      

  3.   


    var VarData:oleVariant;
        byteData:array of byte;sckData.GetData(VarData);VarData获得二进制数据数据后,怎样赋值给byteData并保存到文件中。谁能帮我解决?如果分不够可以再加!
      

  4.   

    function TFilePacket.WriteFile(var Stream: OleVariant;
      const FileName: WideString): SYSINT;
    var
      OutStream:TFileStream;
      p:Pointer;
    begin
      Result:=-1;
      p:=VarArrayLock(Stream);
      OutStream:=TFileStream.Create(String(FileName),fmCreate);
      try
         OutStream.Write(p^,VarArrayHighBound(Stream,1)+1);
      finally
         VarArrayUnlock(Stream);
         OutStream.Free;
      end;
      Result:=0;
    end;
      

  5.   

    unsigned(僵哥),您好!感谢你的回复,按你的方法,运行程序时,编译能通过,执行时OutStream.Free通不过,提示如下:
    Project hpftp.exe raised exception class EAccessViolation with message 'Access violation at address 00D6B3AF. Write of address F001ACD2'
    请问是怎么回事?谢谢!
      

  6.   

    function TFilePacket.WriteFile(var Stream: OleVariant;
      const FileName: WideString): SYSINT;
    var
      OutStream:TFileStream;
      p:Pointer;
    begin
      Result:=-1;
        OutStream:=TFileStream.Create(String(FileName),fmCreate);
       p:=VarArrayLock(Stream);  try
         OutStream.Write(p^,VarArrayHighBound(Stream,1)+1);
      finally
         VarArrayUnlock(Stream);
         OutStream.Free;
      end;
      Result:=0;
    end;
      

  7.   

    昨天那个提示没了,但是执行该代码时,又出现以下提示:
    Project hpftp.exe raised exception class EPrivilege with message 'privileged instruction'
    请问是怎么回事?谢谢!
      

  8.   

    原来是我自己在OutStream.Free执行之后,又运行OutStream.Size所以出错,但是还有一个问题是:
    procedure TForm1.WriteFile(var Stream: OleVariant;
      const FileName: WideString);
    var
      OutStream:TFileStream;
      p:Pointer;
    begin
      //Result:=-1;
      p:=VarArrayLock(Stream);
      OutStream:=TFileStream.Create(String(FileName),fmCreate);
      try
         OutStream.Write(p^,VarArrayHighBound(Stream,1)+1);
      finally
         VarArrayUnlock(Stream);
         OutStream.Free;
      end;
      //Result:=0;
    end;程序能够顺利执行完毕,但是所保存文件却为0字节,不知怎么就保存不了?
      

  9.   

    我快绝望了,还是没解决,难道只能放弃MsWinsck.ocx
      

  10.   

    procedure TForm1.WinsockDataDataArrival(ASender: TObject;
      bytesTotal: Integer);
    var varData:oleVariant;
    begin
     if isDownFile then
      begin
        self.WinsockData.GetData(varData);
        self.Memo1.Lines.Add('bytesTotal:'+inttostr(bytesTotal));
        self.Memo1.Lines.Add('bound:'+inttostr(vararrayhighbound(vardata,1))); 
    分析结果,bytesTotal在不断变化,执行完后的累加和恰好就是所要下载文件的大小,应该是有数据,但是inttostr(vararrayhighbound(vardata,1))始终为-1,可以看出又没数据,难道vardata里没没有数据,明明接收的呀?
      

  11.   

    明明接收的字节数bytesTotal一直在变化,为什么varData里没有数据?
      

  12.   

    欢迎大家加入delphi程序员群 1805366 一起参加技术讨论
      

  13.   

    我认为应该是有数据,关键是怎样从varData里提取数据的问题,varData是oleVariant类型