socket编程高手请进入... 可以先将要发送的长度发送过去,Server端根据发过来的长度将每次接受的加起来,我就是这样作的,自己设计一个流程吧 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 需要注意的是,由于windows默认缓冲区大小为4K,所以当发送长于4K的信息时,比如,从服务端向客户端发送的一个二进制流,在服务端只需要用 Socket.SendStream()就行了,而在客户端就不一样,它将多次触发onread事件,而Delphi又没有定义如“onreadend”之类的事件,因此,必须在接收时程序员自己对数据进行组装。本文采取的方法是先将流长度发给客户端,然后发送流,客户端将接收的数据写进一个流中,当流长度等于服务端发回的长度时,就表明客户端已接收完毕了。对服务端来说,做为sendstream参数的流,会为Socket 所“拥有”,Socket对象结束时,它也将结束,而不要自己去释放它,否则,会触发一个异常。 客户端程序: var Form1: TForm1; c:longint; //服务端发送的字节数m:tmemorystream; implementation {$R *.DFM} procedure TForm1.Button2Click(Sender: TObject); begin clientsocket1.Socket.SendText('gets'); //发送申请,通知服务端需要屏幕图象 end; procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var buffer:array [0..10000] of byte; //设置接收缓冲区 len:integer; ll:string; b:tbitmap; j:tjpegimage; begin if c=0 then //C为服务端发送的字节数,如果为0表示为尚未开始图象接收 begin ll:=socket.ReceiveText; c:=strtoint(ll); //设置需接收的字节数 clientsocket1.Socket.SendText('okok'); //通知服务端开始发送图象else ==================================================begin //以下为图象数据接收部分 len:=socket.ReceiveLength; //读出包长度 socket.ReceiveBuf(buffer,len); //接收数据包并读入缓冲区内 m.Write(buffer,len); //追加入流M中 if m.Size>=c then //如果流长度大于需接收的字节数,则接收完毕 beginm.Position:=0; b:=tbitmap.Create; j:=tjpegimage.Create; try j.LoadFromStream(m); //将流M中的数据读至JPG图像对象J中 b.Assign(j); //将JPG转为BMP Image1.Picture.Bitmap.Assign(b); //分配给image1元件 finally //以下为清除工作 b.free; j.free;clientsocket1.Active:=false; clientsocket1.Active:=true; m.Clear; c:=0; end; end; end; end; =========================================procedure TForm1.FormCreate(Sender: TObject); begin m:=tmemorystream.Create; end; end. 服务端程序: procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); var s,s1:string; desk:tcanvas; bitmap:tbitmap; jpg:tjpegimage; begin s:=socket.ReceiveText; if s='gets' then //客户端发出申请 begin bitmap:=tbitmap.Create; jpg:=tjpegimage.Create; desk:=tcanvas.Create; //以下代码为取得当前屏幕图象 desk.Handle:=getdc(hwnd_desktop); m1:=tmemorystream.Create; //初始化流m1,在用sendstream(m1)发送流后, //它将保留到socket对话结束, //不能用手工free掉,否则会触发异常 with bitmap do begin width:=screen.Width; height:=screen.Height; canvas.CopyRect(canvas.cliprect,desk,desk.cliprect); end; jpg.Assign(bitmap); //将图象转成JPG格式 jpg.SaveToStream(m1); //将JPG图象写入流中 jpg.free; m1.Position:=0; s1:=inttostr(m1.size); Socket.sendtext(s1); //发送图象大小 end; if s='okok' then //客户端已准备好接收图象 begin m1.Position:=0; Socket.SendStream(m1); //发送JPG图象 end; end; wxjh(孤独剑逍遥孤)的方法是正确的! 谢谢大虾的指点,顺便再问下:怎样把流转化为字符串,如何处理,流数据是byte类型,能不能将其转化为字符串? [基础]C#的搞pascal,遇到点string拼接的疑问 [正确就结贴]请教delphi+MDB转化SQLserver的话的一些细节问题 请教:FROM子句错误,谢谢 问一个编程的简单问题。 数据复制 Delphi小站群1578568 有问题.请大家帮忙解决.谢谢@! Delphi中如何使数据溢出时自动给出错误提示 ????????????????? DCOM老问题 紧急求助:如何将Access的表导出为*.dbf文件? 菜鸟一问,我想在delphi里面使用code insight功能,需要按ctrl+space,可是。。。
送的一个二进制流,在服务端只需要用 Socket.SendStream()就行了,而在客户端就不一样,它将多次触发
onread事件,而Delphi又没有定义如“onreadend”之类的事件,因此,必须在接收时程序员自己对数据进行
组装。本文采取的方法是先将流长度发给客户端,然后发送流,客户端将接收的数据写进一个流中,当流长
度等于服务端发回的长度时,就表明客户端已接收完毕了。对服务端来说,做为sendstream参数的流,会
为Socket 所“拥有”,Socket对象结束时,它也将结束,而不要自己去释放它,否则,会触发一个异常。
客户端程序:
var
Form1: TForm1;
c:longint; //服务端发送的字节数
m:tmemorystream; implementation {$R *.DFM}
procedure TForm1.Button2Click(Sender: TObject);
begin
clientsocket1.Socket.SendText('gets'); //发送申请,通知服务端需要屏幕图象
end;
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
buffer:array [0..10000] of byte; //设置接收缓冲区
len:integer;
ll:string;
b:tbitmap;
j:tjpegimage;
begin
if c=0 then //C为服务端发送的字节数,如果为0表示为尚未开始图象接收
begin
ll:=socket.ReceiveText;
c:=strtoint(ll); //设置需接收的字节数
clientsocket1.Socket.SendText('okok'); //通知服务端开始发送图象
else
==================================================begin //以下为图象数据接收部分
len:=socket.ReceiveLength; //读出包长度
socket.ReceiveBuf(buffer,len); //接收数据包并读入缓冲区内
m.Write(buffer,len); //追加入流M中
if m.Size>=c then //如果流长度大于需接收的字节数,则接收完毕
begin
m.Position:=0;
b:=tbitmap.Create;
j:=tjpegimage.Create;
try
j.LoadFromStream(m); //将流M中的数据读至JPG图像对象J中
b.Assign(j); //将JPG转为BMP
Image1.Picture.Bitmap.Assign(b); //分配给image1元件
finally //以下为清除工作
b.free;
j.free;
clientsocket1.Active:=false;
clientsocket1.Active:=true;
m.Clear;
c:=0;
end;
end;
end;
end; =========================================procedure TForm1.FormCreate(Sender: TObject);
begin
m:=tmemorystream.Create; end;
end.
服务端程序: procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
s,s1:string;
desk:tcanvas;
bitmap:tbitmap;
jpg:tjpegimage;
begin
s:=socket.ReceiveText;
if s='gets' then //客户端发出申请
begin
bitmap:=tbitmap.Create;
jpg:=tjpegimage.Create;
desk:=tcanvas.Create; //以下代码为取得当前屏幕图象
desk.Handle:=getdc(hwnd_desktop);
m1:=tmemorystream.Create; //初始化流m1,在用sendstream(m1)发送流后,
//它将保留到socket对话结束,
//不能用手工free掉,否则会触发异常
with bitmap do
begin
width:=screen.Width;
height:=screen.Height;
canvas.CopyRect(canvas.cliprect,desk,desk.cliprect);
end;
jpg.Assign(bitmap); //将图象转成JPG格式
jpg.SaveToStream(m1); //将JPG图象写入流中
jpg.free;
m1.Position:=0;
s1:=inttostr(m1.size);
Socket.sendtext(s1); //发送图象大小
end;
if s='okok' then //客户端已准备好接收图象
begin
m1.Position:=0;
Socket.SendStream(m1); //发送JPG图象
end; end;