通信监控图像传输问题

wyx_sky 2009-03-30 08:23:07
服务器每15秒从在线主机列表中按顺序选择4台电脑,发送截屏命令,服务端接收到图像后,按顺序显示在服务端

通信是tcp CSocket类,图像压缩zlib,服务端new 20M内存,

刚开始都正常。过一会就会出现问题:截屏上部分是黑色,下部分截屏成功的。也有时候,第一次截屏都是全黑色。

我知道bmp图像data是从下到上从左到右顺序的。

通信结构体:
WORD m_wType1; WORD m_wType2;
DWORD m_dwLen; char *m_pbuffer;

这个问题怎么解决,现在我想每秒更新截屏内容,同时监控4台电脑。

还有个小问题。服务端显示图像的对话框,需要点两次关闭才能退出。这是怎么回事啊?


显示图像的代码:
if (m_pImg[0]!=NULL)
{
CRect rc;
CDC*pDC=m_bmp1.GetDC();

int ncolors = (1 <<((LPBITMAPINFOHEADER)m_pImg[0])->biBitCount); if( ncolors> 256 )
ncolors = 0;
GetClientRect(rc);
::StretchDIBits(pDC->m_hDC ,
0,0,rc.Width()/2,rc.Height()/2,
0,0,((LPBITMAPINFOHEADER)m_pImg[0])->biWidth,((LPBITMAPINFOHEADER)m_pImg[0])->biHeight,
(LPBYTE)m_pImg[0]+ (sizeof(BITMAPINFOHEADER) + ncolors * sizeof(RGBQUAD)),
(LPBITMAPINFO)m_pImg[0],
DIB_RGB_COLORS,
SRCCOPY);
CString temp;
temp.Format("主机名:%s", m_socket[0]->m_strHostName);
TextOut(pDC->m_hDC, 0, 0, temp.GetBuffer(0), temp.GetLength());
}



该对话框窗口默认大小为屏幕大小:

int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
MoveWindow(0,0,nScreenWidth,nScreenHeight,FALSE);
...全文
200 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Wenxy1 2009-06-03
  • 打赏
  • 举报
回复
另一种比较好的思路是,参考VNC这个开源软件的做法。
用截取bmp图片是一种简便的方法。
刚开始都正常。过一会就会出现问题:截屏上部分是黑色,下部分截屏成功的。也有时候,第一次截屏都是全黑色。
更改截取频率,例如 10秒截取一次。
wyx_sky 2009-06-03
  • 打赏
  • 举报
回复
图像复杂点,解压就会出问题->即压缩后图像大于1M吧

问题基本解决了,代码不变,debug版本无任何问题,release版本不可用

同样的错误,3个月前也遇到过,具体原因不知道。(我怀疑我电脑的VC6有问题)
解决方法就是...设置工程的优化选项,只要不选择:最快速度

都可以正常运行。


谢谢大家了!

远程开机 release版本不可用 [已结帖,结帖人:wyx_sky]
http://topic.csdn.net/u/20090406/14/3c2cf126-6b00-4f70-b680-a86172a3028c.html
wyx_sky 2009-06-03
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wenxy1 的回复:]
另一种比较好的思路是,参考VNC这个开源软件的做法。
用截取bmp图片是一种简便的方法。
刚开始都正常。过一会就会出现问题:截屏上部分是黑色,下部分截屏成功的。也有时候,第一次截屏都是全黑色。
更改截取频率,例如 10秒截取一次。
[/Quote]

你的意思是发送bmp文件吗?服务端再显示文件?



现在发觉的问题就上图像复杂点,解压就会出问题,分配的是5M的空间呀,够了的。

xiejhzwrgcky 2009-06-03
  • 打赏
  • 举报
回复
ding xia
msdn2009_2010 2009-06-02
  • 打赏
  • 举报
回复
帮顶!
wyx_sky 2009-06-02
  • 打赏
  • 举报
回复
第一次一般都会成功。

接收数据
				uLong ulJieYaSize = 5242880;
int Ans;
switch (msg.m_wType2)
{
case CM_CAPTURE_BMP1:
TRACE1("CM_CAPTURE_BMP1 解压前大小:%u\n",msg.m_dwLen);//debug检查
Ans = uncompress(m_pImgData[0], &ulJieYaSize, (unsigned char *)msg.m_pbuffer, msg.m_dwLen);
TRACE2("CM_CAPTURE_BMP1 返回结果: %d 解压后大小:%u 解压前大小:%u\n",Ans,ulJieYaSize, msg.m_dwLen);//debug检查
break;


之后就是
CM_CAPTURE_BMP1 解压前大小:41065
CM_CAPTURE_BMP1 返回结果: -3 解压后大小:5242880 解压前大小:1307248
CM_CAPTURE_BMP1 解压前大小:41065
CM_CAPTURE_BMP1 返回结果: -3 解压后大小:5242880 解压前大小:1307248
CM_CAPTURE_BMP1 解压前大小:41065
CM_CAPTURE_BMP1 返回结果: -3 解压后大小:5242880 解压前大小:1303936

-3是Z_DATA_ERROR错误 返回0是成功
如果远方屏幕颜色比较单一。那一般又都会成功。
mynamelj 2009-04-03
  • 打赏
  • 举报
回复
利用zlib进行压缩,那你每次发送数据buffer一定要和接收的buffer也就是要处理粘包问题,不然解压是会出错的.

建议你使用RTP协议进行传送
peeek 2009-03-30
  • 打赏
  • 举报
回复
kkkkkkkkkkk.
cnzdgs 2009-03-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wyx_sky 的回复:]
在收包的时候,会不会接收到一点数据,马上就调用receive函数了
[/Quote]
很有可能,接收函数要根据函数返回值来判断收到了多少数据,不可假设每次都收到8KB。
另外,程序中应该对各种可能的出错和失败情况加以判断,至少应该输出一些日志信息,以便分析。
wyx_sky 2009-03-30
  • 打赏
  • 举报
回复
程序是运行在局域网中。

tcp通信默认一个包8kb,压缩后图片是500KB吧。

在收包的时候,会不会接收到一点数据,马上就调用receive函数了

void CMsg::Serialize(CArchive &ar)
{
if (ar.IsStoring())
{
ar<<m_wType1;
ar<<m_wType2;
ar<<m_dwLen;//事先保存要发送的长度
if(m_dwLen != 0)
{
//m_pBuf= new char[dwLen];//new应该在发送前
for(int i=0;i < m_dwLen;i++)
ar << m_pbuffer[i];
}
}
else
{
ar>>m_wType1;
ar>>m_wType2;
ar>>m_dwLen;
if(m_dwLen != 0)
{
m_pbuffer= new char[m_dwLen];
for(int i=0;i < m_dwLen;i++)
ar >> m_pbuffer[i];
}
}
}
oyljerry 2009-03-30
  • 打赏
  • 举报
回复
多增加一些调试信息吧,先定位问题的大概位置等,...先看发送数居前是否正确,然后看是否socket通信有问题,还是接手后处理有问题
cnzdgs 2009-03-30
  • 打赏
  • 举报
回复
这问题不好查,截取、压缩、传输、解压、以及显示都与此有关。建议先在发送数据前和接收数据后加一些判断代码,确定是哪部分出的问题。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧