最近在写一个工程,大体上是这样的:服务器端接收客户端传来的图片数据(SOCKET),服务器为每一个客服端开启一个线程接收图片数据并显示在界面上,运行一段时间后,服务器端会出现ntdll.dll错误(ntdll.dll!778a5654())。如何解决?
监听线程如下:DWORD WINAPI ListenThread(LPVOID lpParam)
{
while(1)
{
ASSERT(pDlg!=NULL);
SOCKET s=accept(pDlg->m_hSocket,NULL,NULL);
if (s!=SOCKET_ERROR)
     {
DWORD d;
         CreateThread(NULL,0,RecvThread,(LPVOID)&s,0,&d);
}
}
return 0;
}
接收图片数据并显示线程如下://接收主线程
DWORD WINAPI RecvThread(LPVOID lpParam)
{
   SOCKET s=*((SOCKET*)lpParam);
    while (1)
{
ASSERT(s!=SOCKET_ERROR);
ASSERT(pDlg!=NULL);
CString str1;
CRect rect;
CDC *pDC;
HDC hDC;
CWnd *pwnd;
struct IDNOM
{
int nom;
}IDNOM;
struct IDNOM id;    //接收客户端编号,用于判断显示的位置
char buffer[1024];
memset(buffer,0,sizeof(buffer));
recv(s,(char *)&id,sizeof(id),0);
int rcv=recv(s,buffer,1024,0);
long lFileSize=atol(buffer);
char *pBuffercc=new char[lFileSize+1];
pBuffercc[0]='\0';
char *pBuf=pBuffercc;
long iTemp = 0;
long m;
m=lFileSize;
int t=1;
while (t)
{
rcv=recv(s,buffer, 1024,0);
for (int i=0; i<=rcv; i++)
{
pBuf[i+iTemp] = buffer[i];
}
iTemp+=rcv;
m-=1024;
if (m<=0)
{
t=0;
}
}
CString str;
str.Format("%d",s);
str+=".JPG";
CFile myFile;
myFile.Open(str,CFile::modeCreate|CFile::modeWrite);
myFile.Write(pBuf,lFileSize);
myFile.Close();
delete []pBuffercc;
str1.Format("%d",s);
str1+=".JPG";
IplImage* m_image;
CvvImage m_CvvImage;
m_image=cvLoadImage(str1);
m_CvvImage.CopyOf(m_image,1);
if (id.nom==1)                        //判断编号,显示到对应ID控件中
{
pwnd=pDlg->GetDlgItem(IDC_STATIC_IMAGE);
pDC=pwnd->GetDC();
hDC=pDC->GetSafeHdc();
pwnd->GetClientRect(&rect);
m_CvvImage.DrawToHDC(hDC,&rect);
cvReleaseImage(&m_image);
DeleteDC(hDC);
pwnd->ReleaseDC(pDC);
DeleteObject(pwnd);
}
else if (id.nom==2)
{
pwnd=pDlg->GetDlgItem(IDC_STATIC_IMAGE1);
pDC=pwnd->GetDC();
hDC=pDC->GetSafeHdc();
pwnd->GetClientRect(&rect);
m_CvvImage.DrawToHDC(hDC,&rect);
cvReleaseImage(&m_image);
DeleteDC(hDC);
pwnd->ReleaseDC(pDC);
DeleteObject(pwnd);
}
else if (id.nom==3)
{
pwnd=pDlg->GetDlgItem(IDC_STATIC_IMAGE4);
pDC=pwnd->GetDC();
hDC=pDC->GetSafeHdc();
pwnd->GetClientRect(&rect);
m_CvvImage.DrawToHDC(hDC,&rect);
cvReleaseImage(&m_image);
DeleteDC(hDC);
pwnd->ReleaseDC(pDC);
DeleteObject(pwnd);
Sleep(100);
}

return 0;
}
多线程imagesocketntdll.dll图片显示

解决方案 »

  1.   

    socket用完都close了吗?
    把调用堆栈发出来看看。
      

  2.   

    SOCKET我是一只保持的,只有在退出的时候,才关闭。客户端会通过返回的SOCKET一直循环发送,那个调用堆栈,我也没有看出什么名堂来!
      

  3.   

    估计for (int i=0; i<=rcv; i++) { pBuf[i+iTemp] = buffer[i];   } 这块可能会有越界
    long iMaxCpyLen = min(rcv, lFileSize - (iTemp + rcv)); //限制长度
    memcpy(pBuf + iTemp, buffer, iMaxCpyLen);
    iTemp += iMaxCpyLen;
      

  4.   

    这样会出现这个错误
    > Server.exe!memcpy(unsigned char * dst, unsigned char * src, unsigned long count)  行 185 Asm
    在memcpy.asm中的
    Dword_align:
            test    edi,11b         ;U - destination dword aligned?
            jnz     short CopyLeadUp ;V - if we are not dword aligned already, align        shr     ecx,2           ;U - shift down to dword count
            and     edx,11b         ;V - trailing byte count        cmp     ecx,8           ;U - test if small enough for unwind copy
            jb      short CopyUnwindUp ;V - if so, then jump        rep     movsd           ;N - move all of our dwords        jmp     dword ptr TrailUpVec[edx*4] ;N - process trailing bytes;rep 出会出现错误!
     我一开始用的方法已经开了那么大的空间,怎么会越界?
      

  5.   

    不用固定的buffer,根据你收的字节数,动态分配内存。
      

  6.   


    DWORD WINAPI ListenThread(LPVOID lpParam)
    {
    while(1)
    {
    ASSERT(pDlg!=NULL);
    SOCKET s=accept(pDlg->m_hSocket,NULL,NULL);  // 这个s是临时变量
    if (s!=SOCKET_ERROR)
         {
    DWORD d;
             CreateThread(NULL,0,RecvThread,(LPVOID)&s,0,&d); // 这里用&s不太好吧,可能出现线程函数开始时s已经被销毁了的情况
    }
    }
    return 0;
    }
    你后面的线程函数来接收数据以及绘图:
    在线程里面边接收边写入文件,写完后给主窗口发个消息,让主窗口去刷新绘图。
    接收文件,最好先接收大小,然后再接收文件数据。
      

  7.   


    先把zhoujielunzhimi指出的问题解决。
      

  8.   

    SOCKET我改了,那我再发个消息给主对话框来绘看哈,会不会出问题!
      

  9.   

    这样改了以后还是会出现memcpy的问题,应该还是内存中出现了问题
      

  10.   

    http://bbs.csdn.net/topics/380167545?page=2
    正好我在看这篇帖子,你可以参考一下接收数据。
    最好试试把你接收到的数据保存为文件,如果文件没问题,你再去绘制
      

  11.   

    用AfxBeiginThread或者_beiginthreadex创建线程试试!
      

  12.   

    DEBUG模式下崩溃CallStack找变量看看溢出的是哪里。手动调试查看变量分析才是王道