这是客户端接收流的代码:
procedure TScreenfrm.ClientSocketRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Buf: array[0..100000] of Byte;
  Len: Integer;
  Bmp: TBitmap;
  TmpStr: string;
begin
  if FStreamSize = 0 then
  begin
    TmpStr := Trim(Socket.ReceiveText);
    if TmpStr = '' then Exit;
    try
      FStreamSize := StrToInt(TmpStr); //接收服务端发过来的准备发送的流的大小
      Socket.SendText(CMD_ReadySend); //给服务端发送已准备好的消息,以便服务端开发发送流
    except end;
  end else
  begin
    Len := Socket.ReceiveLength;
    Socket.ReceiveBuf(Buf, Len);
    FSecondStream.Write(Buf, Len);
    if FSecondStream.Size >= FStreamSize then
    begin
      try
        FSecondStream.Position := 0;
        Bmp := TBitmap.Create;
        Bmp.LoadFromStream(FSecondStream);
        ImgScreen.Picture.Bitmap.Assign(Bmp);
        Bmp.Free;
      finally
        Socket.SendText(CMD_BeginCapScr); //连续抓屏
        FSecondStream.Clear;
        FStreamSize := 0;
      end;
    end;
  end;
end;当 FSecondStream.Size >= FStreamSize 时,并且服务端还没有发过来流大小的时候,
还会触发 ClientSocketRead 事件?怎么回事。另外!求一个快速压缩流的算法。必须快才能满足我的要求,请各位帮帮忙。

解决方案 »

  1.   

    >>当 FSecondStream.Size >= FStreamSize 时,并且服务端还没有发过来流大小的时候,还会触发 ClientSocketRead 事件?建议楼主从下面几个方面去找原因1.使用单步跟踪来调试一下,应该要以发现一些问题;2.你在程序中使用FStreamSize、FSecondStream这两个类成员,来作为通讯的主要标志,要注意初始化,及别程序员别的地方不修改这两个成员3.上面的代码中,    try
          FStreamSize := StrToInt(TmpStr); //接收服务端发过来的准备发送的流的大小
          Socket.SendText(CMD_ReadySend); //给服务端发送已准备好的消息,以便服务端开发发送流
        except end;这个异常except end;中中间没有处理,是一个隐患~~
      

  2.   

    这个问题就是我两个程序同时单步调试发现的!异常没有处理是因为当 FSecondStream.Size >= FStreamSize 时,并且服务端还没有发过来流大小的时候,还会触发 ClientSocketRead 事件,因此 Socket.ReceiveText 接收的文本不是流大小,是一些非数值的乱数据。不处理异常就是为了忽略这些数据。
      

  3.   

    >>Socket.ReceiveText 接收的文本不是流大小,是一些非数值的乱数据应该不会有这种情况的,按照数据的收发原则,你的另一边的只发送数据长度,然后等待CMD_ReadySend到来之后,就将数据发送过来;
    也就是说,你的ClientSocketRead 事件中,第一次接收到长度,之后就会接收到指定长度的数据区;
    接收完了,就存入BMP,显示图片文件;并清空缓冲区,设置FStreamSize回0;也就是说,FSecondStream.Size >= FStreamSize,这个条件,是不会出现>的情况,
    而只有FSecondStream.Size == FStreamSize这种情况这面说的是理想的情况下.也就是说,你的通讯是一对一的通讯,你的客户端不会同时接收来自多个IP的数据;
      

  4.   

    感谢 do2008 的热情解答。
    从下面的网址中可下载全部的源程序,请帮忙调试调试。http://bbs.2ccc.com/attachments/2006/wgqsoft_2006102085843.rar其中 LibCompress、SpzLibrary 两个单元是照抄 DynamicSkinForm 组件包中的代码
      

  5.   

    楼主,应该发短信给我啦~~~介么多帖子,我哪找得来呀,,有空帮楼主看看,我也很菜的~~~~不能包票搞定,还是拉wudi_1982出来看看~~~
      

  6.   

    看了一下代码,提出一点意见1.TScreenfrm.TimerTimer这个timer怎么一直在运行,
    >>  Caption := FCntName+' 的屏幕';
    >>  ClientSocket.Host := FAdress;
    >>  ClientSocket.Port := StrToInt(FPort);
    >>  ClientSocket.Open;
    在它的事件里,一直这样Open,怪怪的,不知道楼主是出于什么考虑?怕连接断开?
      

  7.   

    可以了,楼主,调试完成~~~在RemoteSrv.dpr的untMainSrv单元的ServerSocketClientRead事件中,if LeftStr(TmpStr, Length(CMD_BeginCapScr)) = CMD_BeginCapScr then
      begin
        FSecondStream := TMemoryStream.Create;;
        GetScreen(FSecondStream);
        FSecondStream.Position := 0;//加上这一句,楼主忘记把Stream的Position 复位
        if FFirstStream.Size = 0 then
          FFirstStream.LoadFromStream(FSecondStream)
        else
          CompareStream(FFirstStream, FSecondStream);
        CompressStream(FSecondStream);
        Size := FSecondStream.Size;
        TmpStr := IntToStr(Size);
        Socket.SendText(TmpStr);
      end;这样就可以了
      

  8.   

    太感谢了!
    不过我怎么调着还是一样啊?还是 FSecondStream.Size >= FStreamSize 后继续执行 ServerSocketClientRead 事件!至于那个计时器,很惭愧,我本来是想计时开始时,马上执行 Timer.Enabled := False; 来着,结果忘了!
      

  9.   

    to do2008:
    我是初学网络编程,后来听说 TServerSocket/TClientSocket 已经淘汰不用了,
    所以又想用 TIdTCPServer/TIdTCPClient 来实现相同的功能,可是又受阻,就是我
    开的另一个帖子,你也看了!唉!也没这方面的书籍!真是郁闷!
      

  10.   

    >>>不过我怎么调着还是一样啊?还是 FSecondStream.Size >= FStreamSize 后继续执行
    不是吧,你用的delphi是哪个版本呀,是没有没有打补丁呀,,我的开发环境,编译你的代码,没有问题的呀,图像已经正确传回来了
      

  11.   

    >>后来听说 TServerSocket/TClientSocket 已经淘汰不用了现在的indy这个套件包,作是确实非常的大,从ftp,http,smtp,icmp等等各种网络应用都有,封装得很好,性能也不错.在新的project中,可以采用indy来作开发
    至于 TServerSocket/TClientSocket在一些简单的应用中,还是可以用的,简单直接~~~
      

  12.   

    我用的 Delphi7,确实没有打补丁,我这还是头一次听说 Delphi 还有补丁!图像是可以正确传回来,但是单步调试还是会发现这个问题。
    另外如果将比较流和压缩流的代码去掉,运行一段时间后,只要托动一下客户端的窗体,图像传输就会停止!能重点调试一下我另一个帖子的问题吗!我现在准备放弃 TServerSocket/TClientSocket 了!