最近在写一个工程,大体上是这样的:服务器端接收客户端传来的图片数据(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图片显示
监听线程如下: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图片显示
把调用堆栈发出来看看。
long iMaxCpyLen = min(rcv, lFileSize - (iTemp + rcv)); //限制长度
memcpy(pBuf + iTemp, buffer, iMaxCpyLen);
iTemp += iMaxCpyLen;
> 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 出会出现错误!
我一开始用的方法已经开了那么大的空间,怎么会越界?
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;
}
你后面的线程函数来接收数据以及绘图:
在线程里面边接收边写入文件,写完后给主窗口发个消息,让主窗口去刷新绘图。
接收文件,最好先接收大小,然后再接收文件数据。
先把zhoujielunzhimi指出的问题解决。
正好我在看这篇帖子,你可以参考一下接收数据。
最好试试把你接收到的数据保存为文件,如果文件没问题,你再去绘制