J
jhdzwq
Unregistered / Unconfirmed
GUEST, unregistred user!
我做了一个程序,是在局域网中的一台计算机(A)中运行服务端程序(有固定IP),另一台计算机(B)上运行客户端程序,然后先启动
服务端程序(D6中的Tserversocket)开始侦听,再启动客户端的程序(TClientSocket)连接服务端的计算机,向服务端发出指令,服务端根据客户端
的指令实现对指定区域屏幕的抓取,生成位图写入内存流再把数据压缩(8-12K左右)发到客户端,客户端显示接受数据再解压还原成位图在image中显示。
可是在实际运行中会常常出错,报堆栈溢出和socket错误,还有如果网络流量处于峰值不能正常通信该怎样处理保证能够自动恢复连接?请那为高手多多指教!!
,最好有demo
procedure TClientForm.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
MyBuffer: array[0..10000] of byte; {设置接收缓冲区}
MyReceviceLength: integer;
S,ss: string;
MyBmp: TBitmap;
Myrect : TRect;
begin
Myrect:=Rect(0,0,image1.Width-1,image1.Height-1);
StatusBar1.SimpleText := '正在接收数据......';
if MySize = 0 then {MySize为服务端发送的字节数,如果为0表示为尚未开始图象接收}
begin
S := Socket.ReceiveText;
MySize := Strtoint(S); {设置需接收的字节数}
Clientsocket1.Socket.SendText('ready'); {发指令通知服务端开始发送图象}
end
else
begin {以下为图象数据接收部分}
Endflag:=False;
MyReceviceLength:=socket.ReceiveLength; {读出包长度}
StatusBar1.SimpleText:='正在接收数据,数据大小为:'+inttostr(MySize)+' 字节';
Socket.ReceiveBuf(MyBuffer, MyReceviceLength); {接收数据包并读入缓冲区内}
MyStream.Write(MyBuffer, MyReceviceLength); {将数据写入流中}
if MyStream.Size >= MySize then {如果流长度大于需接收的字节数,则接收完毕}
begin
MyStream.Position:= 0;
MyBmp:=tbitmap.Create;
try
UnCompressBitmap(MyStream,Mybmp);
StatusBar1.SimpleText := '正在显示图像';
Image1.Picture.Bitmap.Assign(MyBmp); {分配给image1元件 }
dis.Canvas.CopyRect(Myrect,ClientForm.Canvas,myrect);
Caption:='ClientScreen '+'图象宽:'+inttostr(Image1.Picture.Bitmap.Width)+ {位图尺寸}
' 图象高:'+inttostr(image1.Picture.Bitmap.Height);
display2Epp;
finally {以下为清除工作 }
MyBmp.free;
Endflag:=True;
if Screenph > 6 then screenph:=1;
ss:='cap '+Scr.Tcs[screenph].Fleft+#9+Scr.Tcs[screenph].Ftop+#9+Scr.Tcs[screenph].Fwidth+#9+scr.Tcs[screenph].Fheight;
Socket.SendText(ss); //添加此句即可连续抓屏;
Screenph:=screenph+1;
MyStream.Clear;
MySize := 0;
end;
end;
end;
end;
procedure TClientForm.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
Errorcode := 0; {不弹出出错窗口}
StatusBar1.SimpleText := '无法与主机' + ClientSocket1.Address + '建立连接!';
ClientSocket1.Close; {如果出错停止抓屏清空数据流}
MyStream.Clear;
Tc.Enabled:=True;
end;
服务端程序
procedure Tserverform.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
S, S1: string;
MyBmp: TBitmap;
begin
overflag:=False;
S := Socket.ReceiveText;
if (pos('cap',s) > 0) and (length(s) > 4) then {客户端发出抓屏幕指令}
begin
try
s:=Trim(copy(s,pos(' ',s),length(s)));
getzdvalue(s,Rectvalue);
MyStream := TMemorystream.Create;{建立内存流}
MyBmp := TBitmap.Create;
Cjt_GetScreen(MyBmp, True); {True表示抓鼠标图像}
mybmp.PixelFormat:=pf4bit;
Mybmp.SaveToStream(myStream);
CompressBitmap(MYStream, clDefault);
MyStream.Position := 0;{注意:必须添加此句}
s1 := inttostr(MyStream.size);{流的大小}
Socket.sendtext(s1); {发送流大小}
finally
MyBmp.free;
end;
end;
if s = 'ready' then {客户端已准备好接收图象}
begin
MyStream.Position := 0;
Socket.SendStream(MyStream); {将流发送出去}
end;
overflag:=True;
end;
服务端程序(D6中的Tserversocket)开始侦听,再启动客户端的程序(TClientSocket)连接服务端的计算机,向服务端发出指令,服务端根据客户端
的指令实现对指定区域屏幕的抓取,生成位图写入内存流再把数据压缩(8-12K左右)发到客户端,客户端显示接受数据再解压还原成位图在image中显示。
可是在实际运行中会常常出错,报堆栈溢出和socket错误,还有如果网络流量处于峰值不能正常通信该怎样处理保证能够自动恢复连接?请那为高手多多指教!!
,最好有demo
procedure TClientForm.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
MyBuffer: array[0..10000] of byte; {设置接收缓冲区}
MyReceviceLength: integer;
S,ss: string;
MyBmp: TBitmap;
Myrect : TRect;
begin
Myrect:=Rect(0,0,image1.Width-1,image1.Height-1);
StatusBar1.SimpleText := '正在接收数据......';
if MySize = 0 then {MySize为服务端发送的字节数,如果为0表示为尚未开始图象接收}
begin
S := Socket.ReceiveText;
MySize := Strtoint(S); {设置需接收的字节数}
Clientsocket1.Socket.SendText('ready'); {发指令通知服务端开始发送图象}
end
else
begin {以下为图象数据接收部分}
Endflag:=False;
MyReceviceLength:=socket.ReceiveLength; {读出包长度}
StatusBar1.SimpleText:='正在接收数据,数据大小为:'+inttostr(MySize)+' 字节';
Socket.ReceiveBuf(MyBuffer, MyReceviceLength); {接收数据包并读入缓冲区内}
MyStream.Write(MyBuffer, MyReceviceLength); {将数据写入流中}
if MyStream.Size >= MySize then {如果流长度大于需接收的字节数,则接收完毕}
begin
MyStream.Position:= 0;
MyBmp:=tbitmap.Create;
try
UnCompressBitmap(MyStream,Mybmp);
StatusBar1.SimpleText := '正在显示图像';
Image1.Picture.Bitmap.Assign(MyBmp); {分配给image1元件 }
dis.Canvas.CopyRect(Myrect,ClientForm.Canvas,myrect);
Caption:='ClientScreen '+'图象宽:'+inttostr(Image1.Picture.Bitmap.Width)+ {位图尺寸}
' 图象高:'+inttostr(image1.Picture.Bitmap.Height);
display2Epp;
finally {以下为清除工作 }
MyBmp.free;
Endflag:=True;
if Screenph > 6 then screenph:=1;
ss:='cap '+Scr.Tcs[screenph].Fleft+#9+Scr.Tcs[screenph].Ftop+#9+Scr.Tcs[screenph].Fwidth+#9+scr.Tcs[screenph].Fheight;
Socket.SendText(ss); //添加此句即可连续抓屏;
Screenph:=screenph+1;
MyStream.Clear;
MySize := 0;
end;
end;
end;
end;
procedure TClientForm.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
Errorcode := 0; {不弹出出错窗口}
StatusBar1.SimpleText := '无法与主机' + ClientSocket1.Address + '建立连接!';
ClientSocket1.Close; {如果出错停止抓屏清空数据流}
MyStream.Clear;
Tc.Enabled:=True;
end;
服务端程序
procedure Tserverform.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
S, S1: string;
MyBmp: TBitmap;
begin
overflag:=False;
S := Socket.ReceiveText;
if (pos('cap',s) > 0) and (length(s) > 4) then {客户端发出抓屏幕指令}
begin
try
s:=Trim(copy(s,pos(' ',s),length(s)));
getzdvalue(s,Rectvalue);
MyStream := TMemorystream.Create;{建立内存流}
MyBmp := TBitmap.Create;
Cjt_GetScreen(MyBmp, True); {True表示抓鼠标图像}
mybmp.PixelFormat:=pf4bit;
Mybmp.SaveToStream(myStream);
CompressBitmap(MYStream, clDefault);
MyStream.Position := 0;{注意:必须添加此句}
s1 := inttostr(MyStream.size);{流的大小}
Socket.sendtext(s1); {发送流大小}
finally
MyBmp.free;
end;
end;
if s = 'ready' then {客户端已准备好接收图象}
begin
MyStream.Position := 0;
Socket.SendStream(MyStream); {将流发送出去}
end;
overflag:=True;
end;