不会有什么问题呀,抓的图转为jpeg以减小数据量,用tcp传输图片,我做的图象监控程序就是这样的,每秒传输1-5桢可调,客户端连接,运行十天半个月没问题。

解决方案 »

  1.   

    传输图片时很慢,慢得完全可以让你认为是已经没用了(事实上也是)
    如果再次发送的话,Server端就会自动退出,
    victorchen_2000:如果你有源代码的话,可不可以给出与大家分享:-)
    zyb:发现了什么吗?!请多多指教:-)
      

  2.   

    victorchen 2000:能否将程序 E-Mail 给我? Thank you
      

  3.   

    BCB:可不可以E一份源程序到我信箱里,或者贴出来与大家分享!:-)
      

  4.   

    那么你有没有是过在单机上运行,如果依旧的话就是你的程序有问题。
    另外应该计算一下所需的传送速度,设jpeg压缩到100k的大图片,modem的话就是两秒一张。
      

  5.   

    我在10M局域网试过,用的是UDP,要源码的话和我联系。
      

  6.   

    动态看对方的屏幕,1秒仅一幅,10M网
    络,优化要了极限,无法提速;
    稳定性可以,连续偷看你一小时,也不停;
    我的程序太大,实是一个BO,
    我正在重新研究SOCKET编程,
    修改以后再发布吧,可能时间较长;
      

  7.   

    我用过,还好用,
    不过没把它转成jpeg格式,
    而是bmp的,很大,
    用tcp传输的,一秒一幅,
    我的局域网是10/100MbaseT的
      

  8.   

    我看大家socket编程技术
    不太成熟,都靠个人经验,问题多多,
    谁也讲不清应具体怎样怎样.
      

  9.   

    我想你在传输的这快有问题...用那的什么nmtp好象要好点
    象这种程序如果在LAN中用这中图象的方法真是有点好笑啊
    为什么不能用MPEG,或RM 快啊!我现在在写个这样的
    可是没有rm,或mpeg压缩的资料,(呵呵主要是我忙的没时间啊)
    谁有给我'油箱'也加点 [email protected]
      

  10.   

    哦 是不是你的timer设的太大啦啊.....去看下好啦
      

  11.   

    如果你知道Lotus的ScreenCamera工作原理!
    就不会在用此方法了将800x600x16bit转为JPEG (要速度<>要压缩比)
    TCP/IP(最慢的协议)
    将JPEG还原一屏数据如此转来一秒以可以了!不如 Hook 一下 windows 的 WM_PAINT 
      

  12.   

    如果你知道Lotus的ScreenCamera工作原理!
    就不会在用此方法了将800x600x16bit转为JPEG (要速度<>要压缩比)
    TCP/IP(最慢的协议)
    将JPEG还原一屏数据如此转来一秒以可以了!不如 Hook 一下 windows 的 WM_PAINT 
      

  13.   

    to  YangJunxx:
       屏幕抓图,用MPG之类解决不了速度问题,瓶颈主要是:抓图太慢,
    经反复在10M网上试验,每幅约需秒左右:
             1.抓图                        0.5秒;
             2.转成jpg传到对方且显示出      0.5秒;
    即使传输不用时间,每秒也只有2幅左右;
    所以快速抓图很重要;
      

  14.   

    victorchen 2000:
    我也想看看你的程序,能不能给我给我mail一份?
    [email protected]
      

  15.   

    我也想要一份源码
    [email protected]
    [email protected]
    有谁知道netmeeting 的抓图原理吗
    局域网可以抓图传avi
      

  16.   

    把Delphi的聊天室例子改改,让ClientSocket给你发Jpg文件不就行了吗?
      

  17.   

    to winsky
    速度根本不能满足要求
      

  18.   

    to bcb 
    o o o 不是啦 就是因为图片不是连续的所以才这样啊
    1。建个图片缓冲 在本地先抓10个JPG或跟多文件再传
    2。用MPEG的STEAM 一样的到理 
      

  19.   

    我用csdn上提供的源程序,测试出抓屏的时间(880*600)为60ms,但传送出去的时间为369ms瓶颈是否为图形的压缩算法
      

  20.   


    我想问题是由于UDP传输协议无校验,当用UDP传输时,由于大图片被拆分成小的数据报发送,而UDP并不进行数据顺序的校验,从而导致接收数据的顺序错误引起的.这需要自己在程序中纠正.另外:BCB 可以发一份源码给我吗?
      

  21.   

    UDP可以最大发送 64K-1数据,可以不用拆分成小的数据报发送,
      

  22.   

    我的是采用C++BUILDER编的,实是BO程序,有几千行,
    TClientSOcket与TServerSocket 控件,
    Socket通讯采用的是异步查询,编的太烦了,
    我不满意。现想改成纯异步的;
    大家好象对SOkcet通讯兴趣很大,苦于无资料,我也一样,
    我最近忙完了工作,准备就编个纯异步方式抓屏
    幕的,试验一下,元旦过后;
      

  23.   

    大家对同步方式感兴趣,我特查了一些的
    Socket编程的书,同步方式问题多多,
    还是异步好,效率高 ,但要解决几个问题:
      1. 对方发来的数据,有延迟,不够规定数目;
                解决办法:放到自已的缓冲区,一旦够了就处理,超过时间算超时;
      2. 防止OnRead事件重入;                                 
      
      

  24.   


    第一步,编制VClient.exe文件。新建Delphi工程,将默认窗体的Name属性设为“Client”。加入TNMUDP控件,Name属性设为“CUDP”;LocalPort属性设为“1111”,让控件CUDP监视受控机的1111端口,当有数据发送到该口时,触发控件CUDP的OnDataReceived事件;RemotePort属性设为“2222”,当控件CUDP发送数据时,将数据发到主控机的2222口。 在implementation后面加入变量定义 const BufSize=2048;{ 发送每一笔数据的缓冲区大小 } 
    var 
    BmpStream:TMemoryStream; 
    LeftSize:Longint;{ 发送每一笔数据后剩余的字节数 } 为Client的OnCreate事件添加代码: 
    procedure TClient.FormCreate(Sender: TObject); 
    begin 
    BmpStream:=TMemoryStream.Create; 
    end; 为Client的OnDestroy事件添加代码: 
    procedure TClient.FormDestroy(Sender: TObject); 
    begin 
    BmpStream.Free; 
    end; 为控件CUDP的OnDataReceived事件添加代码: 
    procedure TClient.CUDPDataReceived(Sender: TComponent; 
    NumberBytes: Integer; FromIP: String); 
    var 
    CtrlCode:array[0..29] of char; 
    Buf:array[0..BufSize-1] of char; 
    TmpStr:string; 
    SendSize,LeftPos,TopPos,RightPos,BottomPos:integer; 
    begin 
    CUDP.ReadBuffer(CtrlCode,NumberBytes);{ 读取控制码 } 
    if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='show' then 
    begin { 控制码前4位为“show”表示主控机发出了抓屏指令 } 
    if BmpStream.Size=0 then { 没有数据可发,必须截屏生成数据 } 
    begin 
    TmpStr:=StrPas(CtrlCode); 
    TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4); 
    LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1)); 
    TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr) 
    -Pos(':',TmpStr)); 
    TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1)); 
    TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)- 
    Pos(':',TmpStr)); 
    RightPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1)); 
    BottomPos:=StrToInt(Copy(TmpStr,Pos(':',TmpStr 
    )+1,Length(TmpStr)-Pos(':',TmpStr))); 
    ScreenCap(LeftPos,TopPos,RightPos,BottomPos); { 
    截取屏幕 } 
    end; 
    if LeftSize>BufSize then SendSize:=BufSize 
    else SendSize:=LeftSize; 
    BmpStream.ReadBuffer(Buf,SendSize); 
    LeftSize:=LeftSize-SendSize; 
    if LeftSize=0 then BmpStream.Clear;{ 清空流 } 
    CUDP.RemoteHost:=FromIP; { FromIP为主控机IP地址 } 
    CUDP.SendBuffer(Buf,SendSize); { 将数据发到主控机的2222口 } 
    end; 
    end; 其中ScreenCap是自定义函数,截取屏幕指定区域, 
    代码如下: 
    procedure TClient.ScreenCap(LeftPos,TopPos, 
    RightPos,BottomPos:integer); 
    var 
    RectWidth,RectHeight:integer; 
    SourceDC,DestDC,Bhandle:integer; 
    Bitmap:TBitmap; 
    begin 
    RectWidth:=RightPos-LeftPos; 
    RectHeight:=BottomPos-TopPos; 
    SourceDC:=CreateDC('DISPLAY','','',nil); 
    DestDC:=CreateCompatibleDC(SourceDC); 
    Bhandle:=CreateCompatibleBitmap(SourceDC, 
    RectWidth,RectHeight); 
    SelectObject(DestDC,Bhandle); 
    BitBlt(DestDC,0,0,RectWidth,RectHeight,SourceDC, 
    LeftPos,TopPos,SRCCOPY); 
    Bitmap:=TBitmap.Create; 
    Bitmap.Handle:=BHandle; 
    BitMap.SaveToStream(BmpStream); 
    BmpStream.Position:=0; 
    LeftSize:=BmpStream.Size; 
    Bitmap.Free; 
    DeleteDC(DestDC); 
    ReleaseDC(Bhandle,SourceDC); 
    end; 
    存为“C:\VClient\ClnUnit.pas”和“C:\VClient\VClient.dpr”, 
    并编译。   第二步,编制VServer.exe文件。新建Delphi工程,将窗体的Name属性设为“Server”。加入TNMUDP控件,Name属性设为“SUDP”;LocalPort属性设为“2222”,让控件SUDP监视主控机的2222端口,当有数据发送到该口时,触发控件SUDP的OnDataReceived事件;RemotePort属性设为“1111”,当控件SUDP发送数据时,将数据发到受控机的1111口。加入控件Image1,Align属性设为“alClient”;加入控件Button1,Caption属性设为“截屏”;加入控件Label1,Caption属性设为“左:上:右:下”;加入控件Edit1,Text属性设为“0:0:100:100”;加入控件Label2,Caption属性设为“受控机IP地址”;加入控件Edit2,Text属性设为“127.0.0.1”; 在implementation后面加入变量定义 
    const BufSize=2048; 
    var 
    RsltStream,TmpStream:TMemoryStream; 为Server的OnCreate事件添加代码: 
    procedure TServer.FormCreate(Sender: TObject); 
    begin 
    RsltStream:=TMemoryStream.Create; 
    TmpStream:=TMemoryStream.Create; 
    end; 为Client的OnDestroy事件添加代码: 
    procedure TServer.FormDestroy(Sender: TObject); 
    begin 
    RsltStream.Free; 
    TmpStream.Free; 
    end; 为控件Button1的OnClick事件添加代码: 
    procedure TServer.Button1Click(Sender: TObject); 
    var ReqCode:array[0..29] of char;ReqCodeStr:string; 
    begin 
    ReqCodeStr:='show'+Edit1.Text; 
    StrpCopy(ReqCode,ReqCodeStr); 
    TmpStream.Clear; 
    RsltStream.Clear; 
    SUDP.RemoteHost:=Edit2.Text; 
    SUDP.SendBuffer(ReqCode,30); 
    end; 为控件SUDP的OnDataReceived事件添加代码: 
    procedure TServer.SUDPDataReceived(Sender: TComponent; 
    NumberBytes: Integer; FromIP: String); 
    var ReqCode:array[0..29] of char;ReqCodeStr:string; 
    begin 
    ReqCodeStr:='show'+Edit1.text; 
    StrpCopy(ReqCode,ReqCodeStr); 
    SUDP.ReadStream(TmpStream); 
    RsltStream.CopyFrom(TmpStream,NumberBytes); 
    if NumberBytes< BufSize then { 数据已读完 } 
    begin 
    RsltStream.Position:=0; 
    Image1.Picture.Bitmap.LoadFromStream(RsltStream); 
    TmpStream.Clear; 
    RsltStream.Clear; 
    end 
    else 
    begin 
    TmpStream.Clear; 
    ReqCode:='show'; 
    SUDP.RemoteHost:=Edit2.Text; 
    SUDP.SendBuffer(ReqCode,30); 
    end; 
    end; 存为“C:\VServer\SvrUnit.pas”和 
    “C:\VServer\VServer.dpr”,并编译。 
      
      

  25.   

    要做成中国的pcanyway了!!
    加油!!
      

  26.   

    给你提出个建议吧,可以大量减少数据处理量(前提是你要抓的屏幕两祯之间的变化不大):
    你在被监控端的内存中建3个位图:
    1、上一祯图象 Image1 
    2、当前屏幕图象 Image2 
    3、(Image2-Image1)=>Image3(Windows的API中有现成的位图计算函数)
    然后将Image3压缩,因为Image3数据量很小,所以压缩会非常快,传输也快。
    这样在监控端你要做的工作就是通过数学方法还原图象而已。为了容错,你只要隔一定时间传输一幅完整图象就可以了。如果Image3图象数据量很小,你可能只需要RLE压缩,不需要压缩成JPEG。
    当你用常规方法不能解决问题时,想想你的方法是否本来就不对,你说呢?
    数学我常常不及格,但是我觉得数学方法很重要,然后才是技术上的实现8)
      

  27.   

    再给你鼓鼓劲:
    1、如果是每秒15祯,两幅图象的差就一定不大。
    2、既然两幅图象的差不大,你就可以每次传输多幅(当然要看实际情况)。
    3、最好在内存中通过API就解决压缩的问题,我想API支持内存中的RLE压缩,没有必要写文件。
    4、既然Image1用过就作废,你可以直接用Image1和Image2进行计算,结果放在Image1中,这样就没有必要用Image3了。
    5、如果解决了问题,50分少了点吧?8)或者完成后你把代码给我一份,我倒不是想拿来卖,只是想满足一下虚荣心 8-> 谢谢。
      

  28.   

    再:
    我说的Image2-Image1指的是XOR逻辑操作。
      

  29.   

    另外:
    你的内存Image采用不同的格式(每象素位数)对运算速度会有不同影响,你可以分别测试一下。见到帖子回个话吧,不知道你看到了没有。
      

  30.   

    Winsky,thank you!i see now!