连续发送截屏图象后的问题!!(100分)

  • 主题发起人 主题发起人 logpie
  • 开始时间 开始时间
L

logpie

Unregistered / Unconfirmed
GUEST, unregistred user!
我用的是逐行扫描,比较SERVER的2副图,如果有不同行则发到CLIENT,CLIENT在画到相应行上
如果除去下面代码中SERVER的TIMER1的部分,程序运行的很好(1024*768的两副完全不同图象
只用不到半秒就接收完毕,并显示正确)。
但现在我在SERVER端加了个TIMER,每1秒截一次屏幕图象放进IMAGE2,然后比较-》发送-》接受
却出现了问题,CLIENT的IMAGE1没有动静,且CPU占有率达100%
请大家看看到底哪出了错?

Client端:
------------------
unit Unit14;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ExtCtrls;

type
TForm1 = class(TForm)
Csk: TClientSocket;
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
Image1: TImage;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure CskRead(Sender: TObject; Socket: TCustomWinSocket);
procedure FormCreate(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
IntFlag:Integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
csk.Active :=true;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
csk.Socket.SendText('cap');
IntFlag:=1;
end;


procedure TForm1.CskRead(Sender: TObject; Socket: TCustomWinSocket);
Var Strdata,s1,s2:String;
MySize,j,x,n:Integer;
Bmp1:TBitmap;
l1,l2:PByteArray;
begin
If intflag=1 then
Begin
memo1.Text :='';
Strdata:=socket.ReceiveText ;//接受所有不同行
memo1.lines.add(Strdata);
socket.SendText('p');
IntFlag:=2;
end;
If IntFlag=2 then
Begin
MySize:=Socket.ReceiveLength;
GetMem(l2,image1.Width *3);
Bmp1:=TBitmap.Create;
Bmp1.Assign(Image1.Picture.Bitmap);
if mysize=image1.Width *3 then//接受到一行
for j:=0 to Memo1.Lines.Count-1 do
begin
sleep(0); // important!!
Socket.ReceiveBuf(l2^,MySize);

s1:=memo1.Lines.Strings[j];

l1:=Bmp1.ScanLine[Strtoint(s1)];

Move(l2^,l1^,MySize);

end;
end;
Image1.Picture.Bitmap.Assign(Bmp1);

Bmp1.Free;
Freemem(l2);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
memo1.Text :='';
end;
end.
------------------------------
Server端:
------------------------------
unit Unit15;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, ExtCtrls, StdCtrls, Buttons;

type
TForm1 = class(TForm)
Sck: TServerSocket;
Image1: TImage;
Image2: TImage;
Memo1: TMemo;
BitBtn1: TBitBtn;
Timer1: TTimer;
procedure SckClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure FormCreate(Sender: TObject);
procedure CapSRC;
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
i:Integer;

implementation

{$R *.dfm}

procedure TForm1.SckClientRead(Sender: TObject; Socket: TCustomWinSocket);
var StrData:String;
l1,l2:PByteArray;
n,x,Activers,k:Integer;
bm1,bm2:TBitMap;
begin
StrData:=Socket.ReceiveText;
if Strdata='cap' then
Begin
memo1.Text :='';
for i:=0 to image1.Height -1 do
Begin
l1:=Image1.Picture.Bitmap.ScanLine;
l2:=Image2.Picture.Bitmap.ScanLine;
if not CompareMem(l1,l2,image1.Width*3) then
Begin
memo1.Lines.Add(inttostr(i));
End;
end;
Socket.SendText(Trim(memo1.Text));
end;
if strdata='p' then
Begin
for i:=0 to image1.Height -1 do
Begin
l1:=image1.Picture.Bitmap.ScanLine ;
l2:=image2.Picture.Bitmap.ScanLine ;
if not CompareMem(l1,l2,image1.Width*3) then //shouldn't use l1<>l2!!
begin

Activers:=Sck.Socket.ActiveConnections ;
for k:=0 to Activers-1 do
Sck.Socket.Connections[k].SendBuf(l2^,image1.Width*3 );
sleep(0); // important
end;

end;

end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
sck.Active :=true;
memo1.Text :='';
end;
procedure TForm1.CapSRC ;
var SRCDC:Longint;
begin
image2.Refresh ;
SRCDC:=GetDC(0);
Bitblt(image2.Canvas.Handle ,0,0,screen.Width ,screen.Height ,SRCDC,0,0,SRCCOPY);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
CapSrc;
end;
end.
 
你的Timer事件中好象没有发送的语句呀
 
我不是在TIMER1里发呀
我是用TIMER连续接屏放竟IMAGE2,再和IMAGE1比较发送
 
>>“比较-》发送-》接受”
但是怎么好象只有比较呢?
 
有啊!
IF STRDATA=‘CAP’那块是比较

IF STRDATA=‘P’那块是发送

 
“CPU占有率达100%”,指Server还是Client?
 
估计是SERVER吧~~因为关了CLIENT还是这样~~

现在关键~是~~CLIENT怎么没动静了呢?
 
你用Sniffer看一下是否有数据传过来了。
 
有有肯定有
我不用TIMER,直接比较2图是成功的~~
加了TIMER后可能是比较那段出问题了~
 
你把Timer的Interval设大一点有变化吗?
 
不行的~
我当初也想等每次处理完后在截屏,可还是不行
而且1000已经够大了。

1024*768的两副完全不同图象
只用不到半秒就接收完毕,并显示正确
 
Timer里的

image2.Refresh ;
SRCDC:=GetDC(0);
Bitblt(image2.Canvas.Handle ,0,0,screen.Width ,screen.Height ,SRCDC,0,0,SRCCOPY);

会不会Image2.Picture.Bitmap.ScanLine;冲突?

你最好设一个标志位,在对Image2刷新操作时停止ScanLine等操作。
 
如果是冲突应该出错呀~~
 
你可以添加一个全局bool变量试一下。在对Image2刷新操作时停止ScanLine等操作,或者
在ScanLine等操作时停止对Image2刷新。很简单的。
 
恩,我换了种想法,不用TIMER,在CLIENT的Image1.Picture.Bitmap.Assign(Bmp1);后加一句
Button2Click(Sender);,在SERVER的If Strdata='cap' then后加CapSRC;
照理也可以连续传呀,而且是在CLIENT每处理完一次数据后进行的
但运行时发现CPU占有率的问题没了,可CLIENT的IMAGE1居然一点都不变~~

真搞不明白!
 
CLIENT是否收到了数据呢?
 
第一次收到了,然后再到Button2Click(Sender);后就好象收不到了

但如果把这句去掉,手工点击BUTTON2,就没有问题
 
发现一个严重问题:如果Server的image2中的图象是已存的BMP,那么发送接受都没问题
如果是运行时用bitblt截的,那么就出现上面的问题!!
截屏代码是:var srcdc:HDC;
srcdc:=getdc(0);
bitblt(image2.canvas.handle,0,0,screen.wiidth,screen.height,srcdc,0,0,srccopy);
image2.refresh;
 
又一个问题,如果IMAGE里事先加载了已存图象,那么在TIMER里用BITBLT截屏回感到明显停顿,速度很慢
如果没有,就很快,没有任何停顿感。

再我的程序里测试了一下,发现只有在IMAGE2事先加载了随便什么图象,再在CLIENTREAD里用
CAPSRC就可以工作,当然,有很明显的停顿感。
 
我发现问题是出在比较上,如果图是在运行时截的。
 
后退
顶部