我现在想作一个屏幕监视软件,客户端直接读取一个jpg文件后,保存到流里面,然后,后 Internet面板最后那两个控件转输(ClientSocket 和 ServerSocket 控件,Delphi 7).**********************************************
**********客户端
var
  nJpgSize:LongInt;
  i,j,n:LongInt;
  nCompletedSize:LongInt;
  tempStream :TMemorystream;
begin
   tempStream:=TMemoryStream.Create;   JPGFile.LoadFromFile('c:\qq.jpg');
   JPGFile.SaveToStream(JPGStream);    nJpgSize:=JPGStream.Size;
    showmessage('will send to server!' + inttostr(nJpgSize));
    edtMsg.Lines.Add('取屏幕完毕!通知服务器接收数据!<size>' + inttostr(nJpgSize) );    JPGStream.Position :=0;
   sendMessageOut('#SumSize=' + inttostr(nJpgSize));
   sleep(300);    if IsServer then
      ServerSocket.Socket.Connections[0].SendStream(JPGStream)
    else
      ClientSocket.Socket.SendStream(JPGStream);
************************************
*********服务器端
procedure TChatForm.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  S:String;
  FullFileStream:TStreamMemmory;  //用于保存最终完整的图片文件流begin
  FullFileStream:=TStreamMemmory.create(); edtMsg.Lines.Add ('Server Socket get new data!');
  if IsStream =false then
  begin
     s:=Socket.ReceiveText;
     Memo2.Lines.Add(S);
     edtGet.Text :=S;
    edtMsg.Lines.Add ('收到数据,但不是流!');
     exit;
  end;   //**** 下面表示是流信息
   nCurrStream_Len:=Socket.ReceiveLength;
   edtMsg.Lines.Add ('Server Socket正在接收流信息[收到的大小' + inttostr(nCurrStream_Len) + ']nSumSize=' +    inttostr(nSumSize));
   Socket.ReceiveBuf(tempbuffer,nCurrStream_Len);
   edtMsg.Lines.Add (' 把数据写入流中 ');   TempStream.WriteBuffer (Mybuffer,nCurrStream_Len);  //把数据写入流中   if CompletedSize < nSumSize then   //CompletedSize:已接收数据    nSumSize:总数据   nCurrStream_Len:当前包的大小
   begin
      FullFileStream.Seek(CompletedSize,soFromBeginning);     //如果不要这两行,则执行到 **here001时出错,且没有任何图像
      FullFileStream.CopyFrom(TempStream,0);                      //如果要这两行,则能显示图像,但图像下半部份混乱,上半部份正常        CompletedSize := CompletedSize +  nCurrStream_Len ;
   end;   if nCurrStream_Len >=nSumSize then  //准备建立jpg
   begin
      TempStream.Position :=0;  //,nCurrStream_Len
      try
         JPGFile.LoadFromStream(TempStream);                  //  **here001
         BitMap.Assign(JPGFile);
         Image1.Picture.Bitmap.Assign(JPGFile);
         refresh;
         StatusBar1.Panels[0].Text :='显示图像......';
         edtMsg.Lines.Add(#13 + '-------------');         
         edtMsg.Lines.Add(#13);
         fmRemoteSRC.Image1 :=image1;
         IsStream:=false;
         if  chkShowBigWindow.Checked then
             showBigWindow();
      finally
         TempStream.Clear;
      end;
   end;end;
ClientSocket.socket.sendstream(JPGStream);
N:=JpGStream.Size;   //假设为 8500 
在服务器端用 ServerSocket 接收.
Var
   Array buff [0..10000] :byte;
   TempStream:TmemoryStream;
Begin
TempStream.Create;   If 没有接收完毕 then
   Begin
           
   End;   End;
******************************************
******************************************问题:
1、在服务器端接收的数据为什幺总是比实际转送前的数据多出几k 的大小(我在接收完毕后作了  TempStream.Size  的读取 )?
2、为什幺无法还原成JPG图片,在建立JPG时总是提示 error #54 或  #45 之头的错误 ?
3、上术代码应该如何改正?
4、有没有繁体或英文版本的邮件内容监视程序?要Free且注册的。( [email protected]  或 http://www.tanyong.com)谢谢各位!

解决方案 »

  1.   

    關於源程序請到www.tanyong.com/ty.rar
    下載請注意:文件裏面有一個 qq.jpg的圖片,把它放到 c:\ 再調試.因為後來我想直接把一個圖片作為流傳送以測試程序的正確性.請各位一定要幫幫我!!
      

  2.   

    1.Socket.ReceiveBuf的返回值不可丢弃,实际收的字节数有可能小于预接收字节数
    2.因为接收数据不正常而导致JPEG文件头定义不准,所以前提是保证接收到的数据正常。
    3.首先解决问题1
    4.偶这没有。
      

  3.   

    unsigned(僵哥(当程序语言成为普及的第三语言之后……)) 請詳細談談問題1
      

  4.   

    unsigned(僵哥(当程序语言成为普及的第三语言之后……)) 請詳細談談問題1
    ================================
    对于Socket.ReceiveBuf
    在调用比如:
    iLen:=Socket.ReceiveLength();//得到的可能是一个比较大的值,比如1450
    而当调用iLen:=Socket.ReceiveBuf(buf,iLen)之后可能并没有接收到预接收的字节数,即可能小于1450,从而此时若仍然1450处理,那么就会数据失真,即多出很多数据,比如实际接收到的是1400,那么若后续丢弃了iLen的值,就可能多出了50个字节。Delphi代码就不多写了,现在贴一小段C++代码,其实原理上面Dephi和CBuilder没多差别,只是语法上的差别罢了。
    //-----------------------------------------------------------
    void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
          TCustomWinSocket *Socket)
    {
       TMemoryStream *tmpMem=new TMemoryStream();
       try
       {
          int iReceiveLength=Socket->ReceiveLength();
          tmpMem->SetSize(iReceiveLength);
          iReceiveLength=Socket->ReceiveBuf(tmpMem->Memory,iReceiveLength);
          tmpMem->SetSize(iReceiveLength);
          tmpMem->Position=0;
          BufferMem->Position=BufferMem->Size;
          BufferMem->CopyFrom(tmpMem,iReceiveLength);
          EnterCriticalSection(&pLockXY);
          try
          {
             CheckReceive();
          }
          __finally
          {
             LeaveCriticalSection(&pLockXY);
          }
       }
       __finally
       {
          tmpMem->Free();
       }
    }
      

  5.   

    謝謝 :unsigned(僵哥(当程序语言成为普及的第三语言
      

  6.   

    謝謝 :unsigned(僵哥(当程序语言成为普及的第三语言