Delphi XE3 印地 10 UDP

Delphi XE3 indy 10 UDP

我想创建一个客户端-服务器 UDP。问题是服务器不能mopulit图片

type
  TPacket = record
    Image: TJPEGImage;
    student: string;
  end;

var
  Image: TBitmap;
  Desktop: TDesktop;
  by: TBytes;
  Packet: TPacket;

implementation

{$R *.dfm}

procedure TDesktop.Button1Click(Sender: TObject);
var
  can: TCanvas;
begin
  can := TCanvas.Create;
  can.Handle := GetWindowDC(GetDesktopWindow);
  ZeroMemory(by, 0);
  Packet.Image := TJPEGImage.Create;
  Image := TBitmap.Create;
  Image.Width := Screen.Width;
  Image.Height := Screen.Height;
  Image.Canvas.CopyRect(
    Rect(0, 0, Screen.Width, Screen.Height),
    can,
    Rect(0, 0, Screen.Width, Screen.Height)
  );
  Packet.Image.Assign(Image);
  Packet.Image.CompressionQuality := 50;
  Packet.student := 'student';
  IdUDPClient1.BufferSize := SizeOf(packet);
  SetLength(by, sizeof(packet));
  Move(packet, by[0], sizeof(packet));
  IdUDPClient1.SendBuffer('127.0.0.1', 5, by);
  Image.Free;
  Packet.Image.Free;
  ReleaseDC(0, can.Handle);
end;

procedure TDesktop.FormShow(Sender: TObject);
begin
  IdUDPServer1.BufferSize:=SizeOf(packet);
end;

procedure TDesktop.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  AData: array of Byte; ABinding: TIdSocketHandle);
begin
  Packet.Image := TJPEGImage.Create;
  Move(AData[0], packet, sizeof(AData));
  Caption := Packet.student;
  Packet.Image.SaveToFile('E:.jpg');
  Packet.Image.Free;
end;

您的 TPacket 包含一个对象指针和一个动态分配的字符串。您不能 将这些值按原样传输到另一台机器,甚至是同一台机器上的另一个进程。您必须将值序列化为原始字节,然后传输和接收字节,然后在接收端将字节反序列化为可用数据。

试试像这样的东西:

procedure ScreenshotToJpgStream(Stream: TStream);
var
  R: TRect;
  can: TCanvas;
  dc: HDC;
  Bmp: TBitmap;
  Jpg: TJPEGImage;
begin
  R := Rect(0, 0, Screen.Width, Screen.Height);
  Jpg := TJPEGImage.Create;
  try
    Bmp := TBitmap.Create;
    try
      Bmp.Width := R.Width;
      Bmp.Height := R.Height;
      can := TCanvas.Create;
      try
        dc := GetWindowDC(0);
        can.Handle := dc;
        try
          Bmp.Canvas.CopyRect(R, can, R);
        finally
          can.Handle := 0;
          ReleaseDC(0, dc);
        end;
      finally
        can.Free;
      end;
      Jpg.Assign(Bmp);
    finally
      Bmp.Free;
    end;
    Jpg.CompressionQuality := 50;
    Jpg.SaveToStream(Stream);
  finally
    Jpg.Free;
  end;
end;

procedure TDesktop.Button1Click(Sender: TObject);
var
  ImageStrm: TBytesStream;
  Student: String;
  Packet: TIdBytes;
  Offset, ImageLen, StudentLen: Integer;
begin
  ImageStrm := TBytesStream.Create;
  try
    ScreenshotToJpgStream(ImageStrm);
    ImageLen := ImageStrm.Size;

    Student := 'student';
    StudentLen := TIdTextEncoding.UTF8.GetByteCount(Student);

    SetLength(Packet, (SizeOf(Integer)*2) + ImageLen + StudentLen);
    Offset := 0;

    CopyTIdLongInt(ImageLen, Packet, Offset);
    Inc(Offset, 4);
    CopyTIdByteArray(ImageStrm.Bytes, 0, Packet, Offset, ImageLen);
    Inc(Offset, ImageLen);
    CopyTIdLongInt(StudentLen, Packet, Offset);
    Inc(Offset, 4);
    CopyTIdString(Student, Packet, Offset, -1, TIdTextEncoding.UTF8);
  finally
    ImageStrm.Free;
  end;

  IdUDPClient1.SendBuffer('127.0.0.1', Port, Packet);
end;

procedure TDesktop.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  AData: array of Byte; ABinding: TIdSocketHandle);
type
  PIdBytes = ^TIdBytes;
var
  ImageStrm: TIdMemoryStream;
  Student: String;
  Offset, Len: Integer;
begin
  Offset := 0;

  Len := BytesToLongInt(PIdBytes(@AData)^, Offset);
  Inc(Offset, 4);

  Assert(Length(AData) >= (Offset+Len));

  ImageStrm := TIdMemoryStream.Create(@AData[Offset], Len);
  try
    Inc(Offset, Len);

    Len := BytesToLongInt(PIdBytes(@AData)^, Offset);
    Inc(Offset, 4);
    Student := BytesToString(PIdBytes(@AData)^, Offset, Len, TIdTextEncoding.U2TF8);

    Caption := Student;
    Jpg := TJPEGImage.Create;
    try
      Jpg.LoadFromStream(ImageStrm);
      Jpg.SaveToFile('E:.jpg');
    finally
      Jpg.Free;
    end;
  finally
    ImageStrm.Free;
  end;
end;