indy 远程桌面UDP数据流问题,来者有分!!

dnahonker 2008-05-06 04:21:12
不知道如下代码有什么问题
接收不到远程桌面

服务端

///////////////////////////////////////
procedure TForm1.Button2Click(Sender: TObject);
var
sendsize:longint;
Buf:array[0..BufSize-1] of char;
begin
if JpegStream.Size = 0 then
snapscreen;
if LeftSize > BufSize then
SendSize := BufSize
else
SendSize := LeftSize;
//将jpegStream内存流读取SendSize大小的数据到缓冲区
jpegStream.ReadBuffer(Buf,sendSize);
LeftSize:=LeftSize-SendSize;
//向客户端发送
try
idudpclient1.SendBuffer(buf,sendsize);
Memo1.Lines.Add(Buf);//测试,这里有数据传输
sleep(10);
except
jpegstream.Clear;
end;
if LeftSize=0 then
jpegStream.Clear;
end;



procedure Tform1.snapScreen();
var
bmpscreen:Tbitmap;
jpegscreen:Tjpegimage;
FullscreenCanvas:TCanvas;
dc:HDC;
sourceRect,destRect:TRect;
begin
//得到屏幕设备
dc:=getdc(0);
//创建画布句柄
fullscreencanvas:=Tcanvas.Create;
fullscreencanvas.Handle:=dc;
//创建存储位图对象
bmpscreen:=Tbitmap.create;
bmpscreen.Width:=screen.Width;
bmpscreen.Height:=screen.Height;
sourcerect:=rect(0,0,screen.Width,screen.Height);
destrect:=rect(0,0,screen.Width,screen.Height);
//将屏幕图象抓取到bmpScreen位图中
bmpscreen.Canvas.CopyRect(sourcerect,fullscreenCanvas,destrect);
//创建储存Jpeg格式的对象
jpegscreen:=Tjpegimage.Create;
//将图象压缩成Jpeg格式,保存到JpegStream内存流中。
jpegscreen.Assign(bmpscreen);
jpegscreen.CompressionQuality:=10;
jpegscreen.SaveToStream(jpegStream);
jpegstream.Position:=0;
LeftSize:=jpegStream.Size;
//释放创建的对象
FullscreenCanvas.Free;
bmpscreen.Free;
jpegscreen.Free;
ReleaseDC(0,DC);
end;

//以上是发送的代码,下面是接收的代码,但是总是接收不到

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
datastringstream:TStringStream;
begin
datastringstream:=TStringStream.Create('');
datastringstream.CopyFrom(AData,AData.Size);
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
Image1.Free;
end;

这里并不能获得远程桌面的截图,请问如何能获取到呢?谢谢各位了。来者有分
别告诉我用TCP,我现在只想知道UDP的,谢谢各位了
...全文
260 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
dnahonker 2008-05-07
  • 打赏
  • 举报
回复
OK了
原来我把datastringstream.free了
非常感谢gzmhero的支持
结贴,给分
gzmhero 2008-05-07
  • 打赏
  • 举报
回复
发送了几次?你确认所有数据都正常发送出去了么? Memo1.Lines.Add(Buf);Memo1里的数据完整么?是所有jpegstream的数据么?

SendBuffer(buf,sendsize); 是不是有返回值,判断发送成功没?


----------头大
dnahonker 2008-05-07
  • 打赏
  • 举报
回复
datastringstream.CopyFrom(AData,AData.Size);

执行这个以后就不往下继续执行了
dnahonker 2008-05-07
  • 打赏
  • 举报
回复
不对
UDPSERVER只触发了一次
dnahonker 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 gzmhero 的回复:]
触发了几次?每次AData.Size和发送的长度对应么?
最后DataStringStream.Size和发送的时候JpegStream.Size长度一致么?
你的程序是反复点击Button2才行,一次只能发送BufSize大小,若比较大,需要你点击多次按钮才行,你这样做了么?
你的JpegStream里的数据是个Jpeg图片,这边Image1.Picture.BitMap.LoadFromStream是不行的,Image不能直接读Jpg文件
var
jpg:TJPEGImage;
begin
jpg:…
[/Quote]

我用time多次点击。
你的代码可以显示图片了
但是只能显示一半
var
datastringstream:tstringstream;
jpg:TJPEGImage;

procedure TForm1.FormCreate(Sender: TObject);
begin
datastringstream:=TstringStream.Create;
jpg:=TJPEGImage.Create;
end;

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
begin
datastringstream.CopyFrom(AData,AData.Size);
if AData.Size < BufSize then //数据已读完
begin
datastringstream.Position:=0;
jpg.LoadFromStream(datastringstream);
Image1.Picture.Bitmap.Assign(jpg);
end;

这里不加if AData.Size < BufSize then //数据已读完 可以显示一半
但是加了就完全不显示了
gzmhero 2008-05-07
  • 打赏
  • 举报
回复
触发了几次?每次AData.Size和发送的长度对应么?
最后DataStringStream.Size和发送的时候JpegStream.Size长度一致么?
你的程序是反复点击Button2才行,一次只能发送BufSize大小,若比较大,需要你点击多次按钮才行,你这样做了么?
你的JpegStream里的数据是个Jpeg图片,这边Image1.Picture.BitMap.LoadFromStream是不行的,Image不能直接读Jpg文件
var
jpg:TJPEGImage;
begin
jpg:=TJPEGImage.Create;
jpg.LoadFromStream(datastringstream);
Image1.Picture.Bitmap.Assign(jpg);



............
dnahonker 2008-05-07
  • 打赏
  • 举报
回复
一语惊醒梦中人

var
datastringstream:tstringstream;

procedure TForm1.FormCreate(Sender: TObject);
begin
datastringstream:=TstringStream.Create;
end;

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
begin
datastringstream.CopyFrom(AData,AData.Size);
if AData.Size < BufSize then //数据已读完
begin
datastringstream.Position:=0;
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
end;

这么写应该没问题了吧。
可是还是读不出来,不知道为什么
难道是发送端有问题?
测试到IdUDPServer1UDPRead被触发了,但是
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
好象没什么动作
gzmhero 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 dnahonker 的回复:]
我刚给的代码跟你写的没出入啊,我就是不明白了。以前没做过类似的东西
测试如果加了
if AData.Size < BufSize then //数据已读完
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
这句不会被执行
我不明白了。
[/Quote]

没出入么?你的代码每次都重新建立一个datastringstream,不会保留前面的数据。

-----------------------------
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
//这句只要最后执行一次就可以了,不是每次都执行。
dnahonker 2008-05-07
  • 打赏
  • 举报
回复
我刚给的代码跟你写的没出入啊,我就是不明白了。以前没做过类似的东西
测试如果加了
if AData.Size < BufSize then //数据已读完
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
这句不会被执行
我不明白了。
gzmhero 2008-05-07
  • 打赏
  • 举报
回复
每次收到数据,都追加到一个数据流的尾部,当所有的数据收完之后,再显示到Image1上就可以了。

var
datastringstream:TStringStream;
....
datastringstream:=TStringStream.Create('');

.......

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
begin
datastringstream.CopyFrom(AData,AData.Size);
if AData.Size < BufSize then //数据已读完
begin
datastringstream.Position:=0;
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
end;
....

这样的逻辑差不多。

--不要等别人给你写完整的代码吧,清楚了逻辑和自己出的问题就可以了,自己去调试。
dnahonker 2008-05-07
  • 打赏
  • 举报
回复
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
datastringstream:TStringStream;
begin
datastringstream:=TStringStream.Create('');
datastringstream.CopyFrom(AData,AData.Size);
datastringstream.position:=0;
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
Image1.Free;
end;

经过测试,发送端发送与接收端接收的数据是一样的,但是还是无法获取远程桌面图片
请问该如何获取?
gzmhero 2008-05-06
  • 打赏
  • 举报
回复
每次看一下:
datastringstream.Position:=0;
datastringstream.DataString///////////是什么内容,对不对。
ly_liuyang 2008-05-06
  • 打赏
  • 举报
回复
如果资源不紧张,还是TCP的好,不会丢失数据,而且连续数据也容易处理很多的
dnahonker 2008-05-06
  • 打赏
  • 举报
回复
IdUDPServer1UDPRead 能正常触发,可是用memo查看接收到的数据与发送的不一样,并且显示不了,请问gzmhero 如何改才可以正常显示出来呢?
gzmhero 2008-05-06
  • 打赏
  • 举报
回复
IdUDPServer1UDPRead 事件能正常触发么,如果能,那你这里的代码改下应该可以了。
如果不能触发,那要看你的通讯设置对不对。

var
datastringstream:TStringStream;
begin
datastringstream:=TStringStream.Create('');
datastringstream.CopyFrom(AData,AData.Size);
if AData.Size < BufSize then //数据已读完
datastringstream.Position:=0;
Image1.Picture.Bitmap.LoadFromStream(datastringstream); //XXXXXXXXXXXXXXXXXXXXX
Memo1.Lines.Add(string(datastringstream));
Image1.Free;

严重不对。逻辑混乱,每次都重新建立一个TStringStream,每次都把数据写在头上,即使接收了,也不会正常显示在Image1上,
而且下边的判断成立之后,才能执行所有的下边的代码。AData.Size是每次的数据包<BufSize基本可以判断是数据读完,唯一例外
是数据刚好是BufSize的整数倍的时候。
dnahonker 2008-05-06
  • 打赏
  • 举报
回复
如何判断数据包的结尾呢?
dnahonker 2008-05-06
  • 打赏
  • 举报
回复
请问该如何接收呢?
我这么写也接收不到
const buffersize=2048;//同发送端的buffersize一样

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
datastringstream:TStringStream;
begin
datastringstream:=TStringStream.Create('');
datastringstream.CopyFrom(AData,AData.Size);
if AData.Size< BufSize then //数据已读完
datastringstream.Position:=0;
Image1.Picture.Bitmap.LoadFromStream(datastringstream);
Memo1.Lines.Add(string(datastringstream));
Image1.Free;
end;

这么写还是接收不到,请问哪出现问题了呢?
gzmhero 2008-05-06
  • 打赏
  • 举报
回复
1、Image1.Picture.Bitmap.LoadFromStream(datastringstream);
//前面要datastringstream.Position:=0;

或者直接用:Image1.Picture.Bitmap.LoadFromStream(ADate);

2、发送的时候,你数据块大会分包来发送,但是接收的地方,直接接收了就放到Image1上了,你确认接收完成了么?
每次接收可能是一包,也可能是很多包才能接收完,你要判断数据包的结尾,然后再显示。
dnahonker 2008-05-06
  • 打赏
  • 举报
回复
应该如何接收呢,请各位帮帮忙

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧