上位机程序,通过多线程的方式,每个设备启动一个发送线程和一个接收线程。
在运行几个小时之后,程序报错,不能运行。实在找不出来原因了,请大家帮我看看程序有什么问题?
这是一个设备的代码,其它的设备处理代码基本相同,
//设备号user_id=2
//列表位置id=1extern CDatabase db;SOCKET clisock_NTC2142;
sockaddr_in conAdd_NTC2142;
HANDLE ProcessHandle_NTC2142;//发送
HANDLE ProcessHandle_NTC2142a;//接收DWORD ThreadID_NTC2142;
DWORD ThreadIDRev_NTC2142;static UINT thread_NTC2142(LPVOID pParam);//NTC2185发送线程
static UINT threadRev_NTC2142(LPVOID pParam);//QPSK接收线程static int sendCmd_NTC2142(CString deviceCmd);//QPSK发送
static int revCmd_NTC2142();
static int analyCmdName(CString cCmd,int iLen);//分析指令名称NTC21852Namestatic int isConn();//判断是否连接
void reSet(CString ipNtc);//NEWTEC NTC2142中频射频切换器  指令21
const char *NTC2142[] = {"Sst?","OOG?"};
const char *NTC2142Name[] = {"设备内部温度","输出增益"};//启动设备1调制器主程序
void NTC2142Master(CString ipNtc)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
CString ipaddress_NTC2142;
CNewTecADlg *dlg=(CNewTecADlg*) AfxGetApp()->GetMainWnd();

ipaddress_NTC2142 = ipNtc;

conAdd_NTC2142.sin_addr.s_addr=inet_addr(ipaddress_NTC2142);
conAdd_NTC2142.sin_family=AF_INET;
conAdd_NTC2142.sin_port=htons(5933);
//创建socket
clisock_NTC2142=socket(AF_INET,SOCK_STREAM,0);

//启动线程
TreadParam* ptp = new TreadParam;
ptp->hWnd = dlg->m_hWnd;
ptp->ip = ipaddress_NTC2142; //发送线程
ProcessHandle_NTC2142 = CreateThread(0,
0,
(LPTHREAD_START_ROUTINE)thread_NTC2142,
ptp,
0,
&ThreadID_NTC2142);

//接收线程
ProcessHandle_NTC2142a = CreateThread(0,
0,
(LPTHREAD_START_ROUTINE)threadRev_NTC2142,
ptp,
0,
&ThreadIDRev_NTC2142); CloseHandle(ProcessHandle_NTC2142);
CloseHandle(ProcessHandle_NTC2142a);
}
//重连
void reSet(CString ipNtc)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );

CString ipaddress_NTC2142;

CNewTecADlg *dlg=(CNewTecADlg*) AfxGetApp()->GetMainWnd();

ipaddress_NTC2142 = ipNtc;

conAdd_NTC2142.sin_addr.s_addr=inet_addr(ipaddress_NTC2142);
conAdd_NTC2142.sin_family=AF_INET;
conAdd_NTC2142.sin_port=htons(5933);
//创建socket
clisock_NTC2142=socket(AF_INET,SOCK_STREAM,0);

//启动线程
TreadParam* ptp = new TreadParam;
ptp->hWnd = dlg->m_hWnd;
ptp->ip = ipaddress_NTC2142;

/*ProcessHandle_NTC2142 = CreateThread(0,
0,
(LPTHREAD_START_ROUTINE)thread_NTC2142,
ptp,
0,
&ThreadID_NTC2142);
*/
CloseHandle(ProcessHandle_NTC2142a);
Sleep(100);
ProcessHandle_NTC2142a = CreateThread(0,
0,
(LPTHREAD_START_ROUTINE)threadRev_NTC2142,
ptp,
0,
&ThreadIDRev_NTC2142);
}
//发送线程
UINT thread_NTC2142(LPVOID pParam)
{
TreadParam * ptp = (TreadParam*)pParam;
HWND hWnd = ptp->hWnd;
CString ip = ptp->ip;

char buff[1000];
memset(buff,0,sizeof(buff));

CSize size;
size.cx=0;
size.cy=30;
int s=1,addcount=0;
CNewTecADlg *dlg=(CNewTecADlg*) AfxGetApp()->GetMainWnd();

//循环获得数据
int i=0;
int n = sizeof(NTC2142)/sizeof(NTC2142[0]);
while(1)
{
   s = sendCmd_NTC2142(NTC2142[i]);
   i = ++ i%n;
   Sleep(500);
}

AfxEndThread(0);
return 0;
}//发送数据
int sendCmd_NTC2142(CString deviceCmd)
{
CNewTecADlg *dlg=(CNewTecADlg*) AfxGetApp()->GetMainWnd();
char buff[100];
char head[] = "\x02\0";//长度为2
char cEnd[] = "\x03\0";//长度为1
char body[]={'0'};
CString strBody;//用户输入内容

memset(buff,0,sizeof(buff));
memset(body,0,sizeof(body));

CSize size;
size.cx=0;
size.cy=30;
//获得发送信息

//strBody="SId?";
strBody=deviceCmd;
strcpy(body,strBody);

int iHeadLen = sizeof(head);
int iBodyLen = strBody.GetLength();
int iEndLen = sizeof(cEnd);
memset(buff,0,sizeof(buff));

memcpy(buff,head,iHeadLen-1);
memcpy(buff+iHeadLen-1,body,iBodyLen);
memcpy(buff+iHeadLen+iBodyLen-1,"\x03",1);

int iBuffLen = iHeadLen+iBodyLen+iEndLen-2;
char cLrc[]={0};

dlg->GetLRC(buff,cLrc,iBuffLen);
int iLrcLen = sizeof(cLrc);

memcpy(buff+iHeadLen+iBodyLen+iEndLen-3,cLrc,iLrcLen);

//发送数据

int retVal = send(clisock_NTC2142,buff,sizeof(buff),0);
//写日志

return retVal;
}//通过主程序传来的指令
int sendCmd2142_Cli(CString deviceCmd)
{
CNewTecADlg *dlg=(CNewTecADlg*) AfxGetApp()->GetMainWnd(); char buff[100]={'0'};
char body[100]={'0'};
memset(body,0,sizeof(body));
memset(buff,0,sizeof(buff));
CString strBody_2142="";//用户输入内容

CSize size;
size.cx=0;
size.cy=30;

strBody_2142=deviceCmd;
strcpy(body,strBody_2142);

buff[0]=0x02;
buff[1]=0x64;
buff[2]=body[0];
buff[3]=body[1];
buff[4]=body[2];
buff[5]=body[3];
buff[6]=body[4];
buff[7]=body[5];
buff[8]=body[6];
buff[9]=body[7];
buff[10]=body[8];
buff[11]=body[9];
buff[12]=body[10];
buff[13]=body[11];
buff[14]=body[12];
buff[15]=body[13];
buff[16]=0x03;

int iBuffLen = 17;
char cLrc[]={0};

dlg->GetLRC(buff,cLrc,iBuffLen);
int iLrcLen = sizeof(cLrc);


buff[17]=cLrc[0];

//发送数据

int retVal = send(clisock_NTC2142,buff,sizeof(buff),0);

retVal = 1;
return retVal;
}int isConn()
{
clisock_NTC2142=socket(AF_INET,SOCK_STREAM,0);
CNewTecADlg *dlg=(CNewTecADlg*) AfxGetApp()->GetMainWnd();
//连接到服务器
int valRet = connect(clisock_NTC2142,(sockaddr*)&(conAdd_NTC2142),sizeof(conAdd_NTC2142));
if(valRet == SOCKET_ERROR)
{
//线路中断
dlg->sLineErr.userId=2;
dlg->sLineErr.alarm=0;//0告警1正常
::SendMessage(dlg->m_hWnd,WM_MY_MESSAGE2,(WPARAM)&dlg->sLineErr,0);

return 0;
}
else
{
//线路中断
dlg->sLineErr.userId=2;
dlg->sLineErr.alarm=1;//0告警1正常
::SendMessage(dlg->m_hWnd,WM_MY_MESSAGE2,(WPARAM)&dlg->sLineErr,0);

return 1;
}
}//接收线程
UINT threadRev_NTC2142(LPVOID pParam)
{
TreadParam * ptp = (TreadParam*)pParam;
HWND hWnd = ptp->hWnd;
CString ip = ptp->ip;

char buff[1000];
memset(buff,0,sizeof(buff));

CSize size;
size.cx=0;
size.cy=30;
int s=1,addcount=0;
CNewTecADlg *dlg=(CNewTecADlg*) AfxGetApp()->GetMainWnd();
//连接到服务器
int iConn=0;

for(int i1=0;i1<5;i1++)
{
iConn=isConn();
if(iConn==1)
{
break;
}
else
{
Sleep(500);
}
}


if (dlg->ee==1)
dlg->m_list.InsertItem(dlg->count++,"连接成功");
dlg->SetForegroundWindow();


//循环获得数据
int i=0;
CString tmp="";


while(s!=SOCKET_ERROR)
{

if(iConn==0)
{
iConn=isConn();
}

//调用recv函数接收数据
s = revCmd_NTC2142();
if(s==SOCKET_ERROR)//没有返回值;重新连接
{
iConn=isConn();
}

//i++;
Sleep(50);
} WSACleanup();
closesocket(clisock_NTC2142);

reSet(ip);
return 0;
}
//发送数据
int revCmd_NTC2142()
{
//TreadParam * ptp = (TreadParam*)pParam;
//HWND hWnd = ptp->hWnd;
CNewTecADlg *dlg=(CNewTecADlg*) AfxGetApp()->GetMainWnd();
char buff[1000];
int s;

CString strBody;//用户输入内容

memset(buff,0,sizeof(buff));

CSize size;
size.cx=0;
size.cy=30;
//获得发送信息

s=recv(clisock_NTC2142,buff,1000,0);
CString strTmp="";
strTmp=buff[5];

if(strTmp=="!")
return s;

dlg->SetForegroundWindow();

if (s!=SOCKET_ERROR)
//dlg->m_list.InsertItem(dlg->count++,buff);

//处理接收内容
CString cCmd="";
CString cNeiRong="";
CString cCmdName="";//指令名称by20071106
int iCmd;//by 20071106

int iBuffLen=sizeof(buff);
strtoul(buff, NULL, 16);
int iLen = sizeof(NTC2142)/sizeof(NTC2142[0]);//by20071106

if(buff[0]==0x06)//接收数据为06表示是正常数据
{
CString cCmd="";
cCmd=dlg->analyCmd(buff,iBuffLen);

cNeiRong = dlg->analyContent(buff,iBuffLen);

iCmd = analyCmdName(cCmd,iLen);

cCmdName=NTC2142Name[iCmd]; dlg->sendCon_NTC2142.id=1;
dlg->sendCon_NTC2142.userId=2;
strcpy(dlg->sendCon_NTC2142.deviceName,cCmdName);//
strcpy(dlg->sendCon_NTC2142.deviceCommand,cCmd);
strcpy(dlg->sendCon_NTC2142.cont,cNeiRong);
dlg->sendCon_NTC2142.sendType=0;

//更新设备值
dlg->m_listdevice.SetItemText(1,1,cCmdName);
dlg->m_listdevice.SetItemText(1,2,cNeiRong);
//写日志
::SendMessage(dlg->m_hWnd,WM_MY_MESSAGE,(WPARAM)&dlg->sendCon_NTC2142,0); }
return s;
}
//分析指令名称
int analyCmdName(CString cCmd,int iLen)
{
CString str=cCmd;
char tmp[1024]={'0'};
CString tmp1="";
int j=iLen;
int iCmd;
for(DWORD i=0;i<(unsigned)iLen;i++)
{
tmp1="";
tmp1=NTC2142[i];

if (tmp1.Left(3)==str)
{
iCmd=i;
break;

}
}

return iCmd;
}

解决方案 »

  1.   

    出错的时候,用编译器查看一下出错的调用堆栈,查找你的代码里什么函数触发的...
    多线程,很有可能各种资源,数据操作,指针等可能引起问题.自己多增加一些调试log等来定位问题
      

  2.   

    Debug下,出错在哪,说清楚下代码这么长没有人会想看
      

  3.   

    debug下没有错误,程序也能正常运行,只是时间长了,就不稳定了。
      

  4.   

    1、用boundcheck看看是不是有泄漏
    2、写点log,看看程序大体在哪里停下来了
      

  5.   

    你new的内存有没有释放?
    TreadParam* ptp = new TreadParam; //启动线程
    TreadParam* ptp = new TreadParam; 
      

  6.   

    1.内存不足或内存操作bug造成程序出错.
    2.系统资源不足,你要建立几千几万个线程肯定出错.
      

  7.   

    我用BoundsChecker跑了一下,报User breakpoint called from code at 020921B9,
    这是具体的内容,我如何确定错误在哪
    02092197   add         byte ptr [edi],al
    02092199   add         byte ptr [edi],al
    0209219B   add         byte ptr [ebp+60000B01h],ch
    020921A1   mov         eax,[0C13CEA0]
    020921A6   test        eax,eax
    020921A8   jne         020921B8
    020921AA   push        offset threadRev_NTC2185 (0041d2f0)
    020921AF   push        dword ptr [esp+10h]
    020921B3   call        0C00D0B2
    020921B8   popad
    020921B9   int         3
    020921BA   mov         ebp,esp
    020921BC   push        0FFh
    020921BE   jmp         threadRev_NTC2185+5 (0041d2f5)
    020921C3   add         byte ptr gs:[eax],al
    020921C6   add         byte ptr [eax],al
    020921C8   push        ebx
      

  8.   

    改了以后,到现在已经运行了40个小时没有出现问题。
    用BoundsChecker测试只有
    void NTC2142Master(CString ipNtc) 中的
    TreadParam* ptp = new TreadParam出现内存溢出,
    void reSet(CString ipNtc) 中的
    clisock_NTC2142=socket(AF_INET,SOCK_STREAM,0); 出现资源溢出,
    我把delete ptp 加上后,程序直接报错无法运行。把closeSocket(clisock_NTC2142)加上还是报资源溢出。
    再跑几天看是否还有问题.
      

  9.   

    delete ptp 加上后,程序直接报错无法运行。
    是否多次释放了内存,或者是不是无效指针。
      

  10.   

    //发送数据 
    int sendCmd_NTC2142(CString deviceCmd)中的
    char body[]={'0'}; 改为body[100]char cLrc[]={0}; 
    好多这种地方,原因就是栈溢出了,你这么写,系统只给它在栈上分配了一个字节,当你后面用到strcpy(body,strBody); 
    栈不溢出我不信
      

  11.   

    我已经改了这些char body[]={'0'}的错误。