远程抓屏的问题(100分)

  • 主题发起人 主题发起人 小虫子:P
  • 开始时间 开始时间

小虫子:P

Unregistered / Unconfirmed
GUEST, unregistred user!
通过抓屏得到远程计算机的一块区域的图象(150X150)
转成jpg用clientsocket传送。用一个timer控制。
在局域网内每秒30次都正常
但是在拨号时,每隔2秒抓一次,每次都是在15分钟左右图象不能显示了。每幅图大概有2k
传送的流程是
timer激发clientsocket发出抓屏信号。
主机抓屏,得到图象的大小。
把大小发给监视机。
监视机准备缓冲区,发出准备好信号。
主机发送图象。
监视机得到并显示出来。

到底是那里出问题呢?
 
嘿嘿,gz
 
我也正在做一个这方面的软件,但是我总觉得用TTIMER控件不如,
在远端计算机上截获消息
 
如果显示完了就抓的话,整个程序就不能干其他的事情了。
我把每次接到的图象的大小都显示在一个label上。
结果发现出错的时候label上显示的是一个很大的数。
就是说它把两次或者三次的大小都放在一起了。
 
这样一般都是缓存溢出的问题,你还是不要设定客户机缓存,改用系统自身的缓存管理,

另外需要改一下发送抓屏请求时,先要判断服务器发送来的数据是否接收完毕,在判断数据已经
全部接收后,再发送抓屏请求命令。
 
具体怎么用系统自身的缓存管理呢[?]
 
好象到目前為止,這個問題在大富翁還沒有一個完美的答案!
幫UP!
 
如果想解决问题,贴一下代码,

SetSockOpt 的 SO_RCVBUF 是用来设置接收缓存,当设定值为 0 时,则为系统自身管理数据缓存

那么在什么时候需要自己定义接收缓存和发送缓存,当你的系统是一个高性能,大并发的系统时
这时有必要自己管理缓存,这就需要好好搞明白 SOCK 的各种选项的用途及其使用界限和相互
配合的问题
 
procedure TForm2.videoclientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
MyBuffer: array[0..10000] of byte; {设置接收缓冲区}
MyReceviceLength: integer;
S: string;
MyBmp: TBitmap;
MyJpg: TJpegimage;
begin
Over := False;//标记是否完成上次发送

if MySize = 0 then {MySize为服务端发送的字节数,如果为0表示为尚未开始图象接收}
begin
S := Socket.ReceiveText;
label2.Caption := s;
MySize := Strtoint(S); {设置需接收的字节数}
VideoClient.Socket.SendText('ready'); {发指令通知服务端开始发送图象}
end
else
begin {以下为图象数据接收部分}
MyReceviceLength := socket.ReceiveLength; {读出包长度}

Socket.ReceiveBuf(MyBuffer, MyReceviceLength); {接收数据包并读入缓冲区内}
MyStream.Write(MyBuffer, MyReceviceLength); {将数据写入流中}
if MyStream.Size >= MySize then {如果流长度大于需接收的字节数,则接收完毕}
begin
MyStream.Position := 0;
MyBmp := tbitmap.Create;
MyJpg := tjpegimage.Create;
try
try
UnCompressBitmap(mystream, myjpg); {将流中的数据读至JPG图像对象中}
MyBmp.Assign(MyJpg); {将JPG转为BMP}
Image2.Picture.Bitmap.Assign(MyBmp);
Image3.Picture.Bitmap.Assign(MyBmp);
except
begin
sendmsg('e','');
seskinbutton19.Click;
seskinbutton14.Click;
end ; /////////////////忽略任何网络错误。
end;
{分配给image元件 }
finally {以下为清除工作 }
MyBmp.free;
MyJpg.free;
Over := True;
MyStream.Clear;
MySize := 0;
end;
end;
end;
end;

procedure TForm2.videoserverClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
S, S1: string;
MyBmp: TBitmap;
Myjpg: TJpegimage;
CompressedStream: TMemoryStream;
begin
S := Socket.ReceiveText;
if S = 'cap' then {客户端发出抓屏幕指令}
begin
compressedstream := tmemorystream.create;
if getforegroundwindow <> form2.Handle then exit;
try
MyStream2 := TMemorystream.Create; {建立内存流}
MyBmp := TBitmap.Create;
Myjpg := TJpegimage.Create;
GetScreen(MyBmp, False); {True表示抓鼠标图像}
Myjpg.Assign(MyBmp); {将BMP图象转成JPG格式,便于在互联网上传输}
Myjpg.CompressionQuality := yasuol; {JPG文件压缩百分比设置,数字越大图像月清晰,但数据也越大}
myjpg.SaveToStream(CompressedStream);
//按缺省的压缩比例对原始图像流进行压缩
CompressBitmap(CompressedStream, clMAX);
//将压缩之后的图像流保存为自定义格式的文件
mystream2.LoadFromStream(compressedstream);
//Myjpg.SaveToStream(MyStream2); {将JPG图象写入流中}
Myjpg.free;
MyStream2.Position := 0; {注意:必须添加此句}
s1 := inttostr(MyStream2.size); {流的大小}
Socket.sendtext(s1); {发送流大小}
finally
MyBmp.free;
end;
end;
if s = 'ready' then {客户端已准备好接收图象}
begin
MyStream2.Position := 0;
Socket.SendStream(MyStream2); {将流发送出去}
end;
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
if over then videoclient.Socket.SendText('cap');
end;
 
有一个问题我很想知道:

大家都在做这个东东到底有什么商业价值?pcanywhere?木马?
 
呵呵,不好说。这个不是个人软件中用到的。
是因为有了市场,才需要这个技术的。
具体的应用范围吗。不好说了。
 
因为我在原来的公司也做过,可是我努力了很久
(大约有两个月)做出的效果也没有pcanywhere好。
我大概看了一下你的代码,还有很多地方是可以改进的。
比如:JPG是有损压缩,如要保证图像不变形要用无损压缩
 
你的qq交流一下?
 
欢迎大家交流
我的qq:26040636
 
问题我自己解决了[:D]
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部