procedure TForm1.Button3Click(Sender: TObject);
var
  SendPack: Pack;
  Stream: TMemoryStream;
  PackLen: Integer;
  SendArray: array of Byte;
  i: Integer;
begin
  SendPack.S := Edit1.Text;
  SendPack.I := SpinEdit1.Value;
  SendPack.B := TMemoryStream.Create;
  Stream     := TMemoryStream.Create;
  try
    Image1.Picture.Bitmap.SaveToStream(Stream);
    SendPack.B.LoadFromStream(Stream);
    PackLen := SizeOf(SendPack);
    SetLength(SendArray, PackLen);
    CopyMemory(@SendArray, @SendPack, PackLen);
    ClientSocket1.Socket.SendBuf(SendArray[0], PackLen);
    for i := 0 to PackLen - 1 do
      ShowMessage('SendArray[' + IntToStr(i) + '] : ' + #9 + Char(SendArray[i]));
  finally
    Stream.Free;
    SendPack.B.Free;
  end;
end;procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  RecePack: Pack;
  Stream: TMemoryStream;
  ReceArray: array of Byte;
begin
  Memo1.Lines.Add('來自:' + Socket.RemoteAddress + '。大小:' + IntToStr(Socket.ReceiveLength));
  SetLength(ReceArray, Socket.ReceiveLength);
  Socket.ReceiveBuf(ReceArray[0], Socket.ReceiveLength);
  Stream := TMemoryStream.Create;
  RecePack.B := TMemoryStream.Create;
  try    Edit2.Text := RecePack.S;
    SpinEdit2.Value := RecePack.I;
    RecePack.B.Position := 0;
    Image2.Picture.Bitmap.LoadFromStream(RecePack.B);
  finally
    Stream.Free;
    RecePack.B.Free;
  end;
end;請指出我上面的錯誤加以改正。謝謝。

解决方案 »

  1.   


    type
      Pack = Record
        S: String;
        I: Integer;
        B: TMemoryStream;
      end;
    這是記錄類型的定義。剛忘了一起發上來了。
      

  2.   

    procedure TForm1.Button3Click(Sender: TObject);
    var
      SendPack: Pack;
      Stream: TMemoryStream;
      PackLen: Integer;
      SendArray: array of Byte;
      i: Integer;
    begin
      SendPack.S := Edit1.Text;
      SendPack.I := SpinEdit1.Value;
      SendPack.B := TMemoryStream.Create;
      Stream     := TMemoryStream.Create;//这句多余
      try
        Image1.Picture.Bitmap.SaveToStream(SendPack.B);
        //SendPack.B.LoadFromStream(Stream);
        PackLen := SizeOf(SendPack);
        SetLength(SendArray, PackLen);
        CopyMemory(@SendArray, @SendPack, PackLen);
        ClientSocket1.Socket.SendBuf(SendArray[0], PackLen);
        for i := 0 to PackLen - 1 do//你要弹出多少个对话框呀,你能忙得过来吗
          ShowMessage('SendArray[' + IntToStr(i) + '] : ' + #9 + Char(SendArray[i]));
      finally
        Stream.Free;//Stream完全可以省略
        SendPack.B.Free;
      end;
    end;//这会儿忙了,先回答到这里
      

  3.   

    PackLen := SizeOf(SendPack);
    这句的问题最大, Sizeof(SendPack)所获得的是Pack这个记录类型所占空间的大小, 为12。
      

  4.   

    顶楼上Pack的内容在内存里根本不连续,所以CopyMemory肯定不能用
    还有,你服务器解包是怎么解的? delphi默认的结构内是4字节对齐的.就是说,比如你pack里面有个byte,在内存中实际上是占了4个字节.压缩的时候约定不一样,解包就会出错. 一般在不同机器间专递数据,特别是两端的程序用不同语言编写的时候,结构都是用紧缩模式,你可以在project->options->compiler->record field alignment中设置,或者在pack的定义前使用{$A1}预编译指令
      

  5.   

    1:
      Pack = Record
        S: String;
        I: Integer;
        B: TMemoryStream;
      end;2:
    Socket.SendBuf(var Buf; Count: Integer);1中,Pack包含字段有string或对象类型,这些字段只是指针,真正内容在指向的地方
    2中,sendbuf中的buf是连续不断的内存空间,将它发送出去。你觉得2中会有1中的string/object指向的内容发给另一方吗?