我在server端和client端都使用Filestream來發送和接收文件,文件可以接收,文件大小一樣(右擊文件,查看屬性,接收文件的大小包括括號裡的位元組和來源文件的也一字不差),但文件的圖標卻是DOS執行文件的圖標,雙擊該文件後提示:
'c:\test.exe僅完成部分的readprocessmemory或writeprocessmemory要求.'
請問會是什麼原因造成的?如何解決?
我在接收完文件後有Filestream.Free;
還有奇怪的是當服務端和客戶端都在自已機子上運行時卻可正常打開文件.

解决方案 »

  1.   

    信譽值低我也不想,只是提過好幾條問題都未得到解決的方法,甚至都沒有回覆,所以沒有結貼導致.
    煩請幫我看看,謝謝.
    主要代碼如下:
    client端:
    rcv := Socket.ReceiveText;
     left := filesize - count;
      if AnsiPos('go~',rcv)=1 then
      begin
        if sizeof(buf2)<left then
        begin
           fs.Read(buf2,sizeof(buf2));  //fs=filestream
          Socket.SendBuf(buf2,sizeof(buf2));
          count := count + sizeof(buf2);
        end
        else
        begin
          fs.Read(buf2,left);
          Socket.SendBuf(buf2,left);
          fs.Free;
          end;server端:
    len:=socket.ReceiveLength;
    if len<8  then
    begin
    rcv:=socket.ReceiveText;
    filesize:=strtoint(rcv);
    count:=0;
    socket.SendText('go~');
    end
    else
    begin
    left:=filesize-count;
    if sizeof(buf2)<left then
    begin
    socket.ReceiveBuf(buf2,sizeof(buf2));
    fs.Write(buf2,sizeof(buf2));  //fs=filestream
    count:=count+sizeof(buf2);
    socket.SendText('go~');
    end
    else
    begin
    socket.ReceiveBuf(buf2,left);
    fs.Write(buf2,left);
    fs.free;
    socket.Close;
    end;
    end;  
      

  2.   

    楼主在通讯协议与代码编写有好几个缺陷,
    但最明显的错误是这句.你没有判断返回值.这个方法的返回值是实际接收的字节数.
    不要理解成想去接收sizeof (buf2)这么大的数据就能读到.socket.ReceiveBuf(buf2,sizeof(buf2));
      

  3.   

    给你写了个简单的例子,你参考参考吧,只有文件传输的部分,没其他握手协议,NonBlock模式,ADSL网络测试没问题,传输14M大小的文件
    ---------------
    服务器端
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ScktComp, StdCtrls;type
      TForm1 = class(TForm)
        ServerSocket1: TServerSocket;
        Button1: TButton;
        procedure ServerSocket1ClientRead(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ServerSocket1ClientConnect(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ServerSocket1ClientDisconnect(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      FS: TFileStream;implementation{$R *.dfm}procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      Buf: array [0..1023] of Byte;
      iRecv: Integer;
    begin
      iRecv := Socket.ReceiveBuf(Buf, SizeOf(Buf));//iRecv是每次实际接收到的字节数
      FS.Write(Buf, iRecv);//隐含了每次Write后FS的当前位置都会到FS结尾
    end;procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      FileName: string;
    begin
      FileName := 'C:\a.ttt';
      if FileExists(FileName) then DeleteFile(FileName);
      FS := TFileStream.Create(FileName, fmCreate);
    end;procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    begin
      FS.Free;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      ServerSocket1.Open;
    end;end.
    --------------
    客户端
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ScktComp;type
      TForm1 = class(TForm)
        ClientSocket1: TClientSocket;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure ClientSocket1Connect(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ClientSocket1Disconnect(Sender: TObject;
          Socket: TCustomWinSocket);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      FS: TFileStream;
    implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    begin
      ClientSocket1.Open;
      FS := TFileStream.Create('C:\aaa.bin', fmOpenRead);
    end;procedure TForm1.ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    begin
      Socket.SendStream(FS);
    end;procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    begin
      FS.Free;
    end;end.
      

  4.   

    楼主贴出了不错的例子..补充一下关于Socket.SendStream
    实际上在ScktComp.pas单元可看源码.
    function TCustomWinSocket.SendStreamPiece: Boolean;其源码简化了就是这样:      while True do
          begin
            StartPos := FSendStream.Position;
            AmountInBuf := FSendStream.Read(Buffer, SizeOf(Buffer));
            if AmountInBuf > 0 then
            begin
              AmountSent := send(FSocket, Buffer, AmountInBuf, 0);
              if AmountSent = SOCKET_ERROR then
              begin
                ErrorCode := WSAGetLastError;
                if ErrorCode <> WSAEWOULDBLOCK then
                begin
                  .....
                end else
                begin
                  FSendStream.Position := StartPos;//准备下次重读出后再传(非阻塞模式)
                  Break;
                end;
              end else if AmountInBuf > AmountSent then
                FSendStream.Position := StartPos + AmountSent//累计发送的字节
              else if FSendStream.Position = FSendStream.Size then
              begin
                 传完结束break;
              end;
            end 
          end;
      

  5.   

    謝謝二位的幫忙,我的問題解決了.
    發送用sendstream,接收用
    socket.receive(buf,len);
    filestream.write(buf,len);
    ........
    ...........
    可否再請教一個小問題:
    用此方法有沒有傳送文件大小的限制?
    我試過傳送30MB的文件,一切正常.
      

  6.   

    非常感谢postren(小虫【最近比较忙】) 贴出的代码,我奋战了两天终于看到一个正确的复制了.
    下面改进有信心了