我这线程问题多的没法说了 哪位高人能帮忙找些错误出来?
在表格里数据显示也有问题UINT nSinglePort;TCHAR temp[10] = "\0";
m_cProgress.SetPos(0); //设置进度条当前位置
m_cResult.DeleteAllItems(); //删除列表所有的项,不然新的就会加到原来项的后面
//清空列表框
POSITION p = m_pStatusList->GetHeadPosition();//建立初始位置,并返回结点指针
while (p)
{
POSITION temp = p;
DATA* pNode = (DATA*)m_pStatusList->GetNext(p);//获取用于反复的下一个元素
m_pStatusList->RemoveAt(temp);//删除指定位置处的节点
//循环删除
if (pNode)
delete pNode;
}
////验证IP地址是否为空
//if (m_cIP.IsBlank())
//{
// MessageBox(_T("请输入IP地址."),
// _T("Error"),
// MB_OK | MB_ICONEXCLAMATION);
// return;
//}
//BYTE f1,f2,f3,f4;
////验证IP地址是否正确
//if (m_cIP.GetAddress(f1,f2,f3,f4) < 4)//有效区域小于4
//{
// MessageBox(_T("请确认IP地址."),
// _T("Invalid IP address"),MB_OK | MB_ICONEXCLAMATION);
// return;
//}
//进行IP地址转化
//CString btnTxt,IP;
//IP = _itoa(f1,temp,10);//将整数IP转化为一个字符串
//IP += _T('.');
//IP += _itoa(f2,temp,10);//将整数IP转化为一个字符串
//IP += _T('.');
//IP += _itoa(f3,temp,10);//将整数IP转化为一个字符串
//IP += _T('.');
//IP += _itoa(f4,temp,10);//将整数IP转化为一个字符串
IP="123.9.212.55";
m_cBtnStop.EnableWindow();
m_cBtnScan.EnableWindow(FALSE);
//是否是单个端口扫描
if (m_bSinglePort) //如果单个扫描值不为0
{
CString port;
m_cSinglePort.GetWindowText(port);//获取单扫描文本控件内的数据
m_minPort = m_maxPort = nSinglePort = atoi(port);//将字符串转换为整数类型
}
else//多端口
{
CString port1,port2;
m_cPortFrom.GetWindowText(port1);//获取多个扫描文本控件内的数据
m_cPortTo.GetWindowText(port2);//获取多个扫描文本控件内的数据
m_minPort = atoi(port1);//将字符串转换为整数类型
m_maxPort = atoi(port2);//将字符串转换为整数类型
m_cProgress.SetRange32(0,m_maxPort-m_minPort+1);//进度栏的最小值与最大值
m_cProgress.SetStep(1);//设置进度栏步长
}if (!m_bSinglePort && m_maxPort < m_minPort)//错误判断
{
MessageBox(_T("最大端口要大于最小端口."),
_T("Caution"),
MB_OK | MB_ICONINFORMATION);
return;
}
UINT m_nMaxAttempts = GetDlgItemInt(IDC_EDIT_ATTEMPTS);//将扫描次数的内容转换为整形数据
for (m_nCounter = m_minPort; m_nCounter <= m_maxPort; m_nCounter++)//循环扫描端口
{
AfxBeginThread(&CPortScanView::thread,this);
MSG message;
//以下消息用于等待Post出去的消息被响应,或者在限定时间内任务是否成功执行
//以下消息可以在执行这个函数时不至于没办法响应用户的操作
if (::PeekMessage(&message,NULL,0,0,PM_REMOVE))//为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。PM_REMOVE:PeekMessage处理后,消息从队列里除掉。
{
::TranslateMessage(&message);//该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。
::DispatchMessage(&message);//该函数调度一个消息给窗口程序
}
m_cProgress.StepIt();//按照当前步长更新进度栏位置
}
//设定状态栏
m_parent->SetStatusBarText((CString)_T("完毕"));//状态栏上显示文字
m_cBtnScan.EnableWindow();
m_cBtnStop.EnableWindow(FALSE);UINT CPortScanView::thread(LPVOID param1)
{
//((CPortScanView*)param1)->critical_section.Lock();
CPortScanView *param= new CPortScanView; param=(CPortScanView*)param1;
// ((CPortScanView*)param1)->critical_section.Unlock();
BOOL bIsOpen = FALSE;
UINT nAttempt = 1;
TCHAR temp[10]="\0";
UINT nIndex = 0;//索引
while(nAttempt <= ((CPortScanView*)param)->m_nMaxAttempts && !bIsOpen)//扫描次数并且标记不为假
{
CString str = _T("连接端口# ");
#ifdef _UNICODE
str += _itow(m_nCounter,temp,10);
#else
str += itoa(((CPortScanView*)param)->m_nCounter,temp,10);//将整数端口转化为一个字符串
#endif
str += _T(", IP地址=");
str += ((CPortScanView*)param)->IP;
str += _T(", Attempt=");
#ifdef _UNICODE
str += _itow(nAttempt,temp,10);
#else
str += itoa(nAttempt,temp,10);//将整数次数转化为一个字符串
#endif
//设定状态栏
((CPortScanView*)param)->m_parent->SetStatusBarText(str);//在状态栏显示字符串
str.Empty();//str的值变了. 将NULL字节放入CString
CTheSocket* pSocket;//Socket的派生类
pSocket = new CTheSocket;
ASSERT(pSocket);//如果条件返回错误,则终止程序执行
//创建socket
if (!pSocket->Create())//产生一个Socket句柄
{
//如果创建失败,则删除,返回 false
delete pSocket;
pSocket = NULL;
bIsOpen = FALSE;
}
//AfxMessageBox(itoa(((CPortScanView*)param)->m_nCounter,temp,10)) ;
//连接被连接的主机地址和指定端口
while (!pSocket->Connect(((CPortScanView*)param)->IP, ((CPortScanView*)param)->m_nCounter))//与未连接的数据流或数据报套接字进行连接(IP,端口)
{
//如果失败返回false
delete pSocket;
pSocket = NULL;
break;
// return FALSE;
}
//关闭Socket 连接并释放所有关联的资源
//pSocket->Close();
delete pSocket;
//return TRUE;//((CPortScanView*)param)->critical_section.Lock();
if (bIsOpen)//如果连接成功
{
DATA* pNode = new DATA;//自定义结构
ASSERT(pNode);//如果条件返回错误,则终止程序执行
//IP.GetLength()将返回字符串所占字节的数目
//GetBuffer为一个CString对象重新获取CString中的字符buffer,返回的LPTSTR为非const的
strcpy(pNode->IPAddress,((CPortScanView*)param)->IP.GetBuffer(((CPortScanView*)param)->IP.GetLength()));//把IP拷贝到DATA结构体的IPAddress
strcpy(pNode->port,_itoa(((CPortScanView*)param)->m_nCounter,temp,10));//将端口转换为字符拷贝到DATA结构体的port
pNode->bStatus = 1;//打开状态 1 = open , 0 = close
pNode->nAttempts = nAttempt;//扫描次数
((CPortScanView*)param)->AddItem(nIndex,0,((CPortScanView*)param)->IP);//在表格内添加IP记录
((CPortScanView*)param)->AddItem(nIndex,1,itoa(((CPortScanView*)param)->m_nCounter,temp,10));//在表格内添加端口记录
if (bIsOpen)
{
((CPortScanView*)param)->AddItem(nIndex,2,_T("打开"));
((CPortScanView*)param)->AddItem(nIndex,4,_T("*"));
}
else
{
((CPortScanView*)param)->AddItem(nIndex,2,_T("关闭"));
((CPortScanView*)param)->AddItem(nIndex,4,_T(" "));
}
((CPortScanView*)param)->AddItem(nIndex++,3,_itoa(1,temp,10));///在表格内添加扫描次数 //((CPortScanView*)param)->m_pStatusList->AddTail(pNode);//将一个元素(或另一个数组中的所有元素)添加到列表的尾部(产生一个新的尾部) }
//试图连接次数
nAttempt++;//次数++
//如果还是无法扫描成功
if (!bIsOpen)//如果连接失败
{
DATA* pNode = new DATA;//自定义结构
ASSERT(pNode);//如果条件返回错误,则终止程序执行
//IP.GetLength()将返回字符串所占字节的数目
//GetBuffer为一个CString对象重新获取CString中的字符buffer,返回的LPTSTR为非const的
strcpy(pNode->IPAddress,((CPortScanView*)param)->IP.GetBuffer(((CPortScanView*)param)->IP.GetLength()));//把IP拷贝到DATA结构体的IPAddress
strcpy(pNode->port,_itoa(((CPortScanView*)param)->m_nCounter,temp,10));//将端口转换为字符拷贝到DATA结构体的port
pNode->bStatus = 0; //关闭状态 1 = open , 0 = close
pNode->nAttempts = nAttempt-1;//扫描次数--
((CPortScanView*)param)->AddItem(nIndex,0,((CPortScanView*)param)->IP);//在表格内添加IP记录
((CPortScanView*)param)->AddItem(nIndex,1,itoa(((CPortScanView*)param)->m_nCounter,temp,10));//在表格内添加端口记录
if (bIsOpen)
{
((CPortScanView*)param)->AddItem(nIndex,2,_T("打开"));
((CPortScanView*)param)->AddItem(nIndex,4,_T("*"));
}
else
{
((CPortScanView*)param)->AddItem(nIndex,2,_T("关闭"));
((CPortScanView*)param)->AddItem(nIndex,4,_T(" "));
}
((CPortScanView*)param)->AddItem(nIndex++,3,_itoa(1,temp,10));///在表格内添加扫描次数
//((CPortScanView*)param)->m_pStatusList->AddTail(pNode);//将一个元素(或另一个数组中的所有元素)添加到列表的尾部(产生一个新的尾部)
}
//((CPortScanView*)param)->critical_section.Unlock();
}
//POSITION pos = ((CPortScanView*)param)->m_pStatusList->GetHeadPosition();//建立初始位置,并返回结点指针
////循环插入扫描结果
//
//
// // DATA* pNode;// = (DATA*)((CPortScanView*)param)->m_pStatusList->GetNext(pos);//获取用于反复的下一个元素
// ((CPortScanView*)param)->AddItem(nIndex,0,((CPortScanView*)param)->IP);//在表格内添加IP记录
// ((CPortScanView*)param)->AddItem(nIndex,1,itoa(((CPortScanView*)param)->m_nCounter,temp,10));//在表格内添加端口记录
// if (bIsOpen)
// {
// ((CPortScanView*)param)->AddItem(nIndex,2,_T("打开"));
// ((CPortScanView*)param)->AddItem(nIndex,4,_T("*"));
// }
// else
// {
// ((CPortScanView*)param)->AddItem(nIndex,2,_T("关闭"));
// ((CPortScanView*)param)->AddItem(nIndex,4,_T(" "));
// }
// ((CPortScanView*)param)->AddItem(nIndex++,3,_itoa(1,temp,10));///在表格内添加扫描次数 return 0;
}
在表格里数据显示也有问题UINT nSinglePort;TCHAR temp[10] = "\0";
m_cProgress.SetPos(0); //设置进度条当前位置
m_cResult.DeleteAllItems(); //删除列表所有的项,不然新的就会加到原来项的后面
//清空列表框
POSITION p = m_pStatusList->GetHeadPosition();//建立初始位置,并返回结点指针
while (p)
{
POSITION temp = p;
DATA* pNode = (DATA*)m_pStatusList->GetNext(p);//获取用于反复的下一个元素
m_pStatusList->RemoveAt(temp);//删除指定位置处的节点
//循环删除
if (pNode)
delete pNode;
}
////验证IP地址是否为空
//if (m_cIP.IsBlank())
//{
// MessageBox(_T("请输入IP地址."),
// _T("Error"),
// MB_OK | MB_ICONEXCLAMATION);
// return;
//}
//BYTE f1,f2,f3,f4;
////验证IP地址是否正确
//if (m_cIP.GetAddress(f1,f2,f3,f4) < 4)//有效区域小于4
//{
// MessageBox(_T("请确认IP地址."),
// _T("Invalid IP address"),MB_OK | MB_ICONEXCLAMATION);
// return;
//}
//进行IP地址转化
//CString btnTxt,IP;
//IP = _itoa(f1,temp,10);//将整数IP转化为一个字符串
//IP += _T('.');
//IP += _itoa(f2,temp,10);//将整数IP转化为一个字符串
//IP += _T('.');
//IP += _itoa(f3,temp,10);//将整数IP转化为一个字符串
//IP += _T('.');
//IP += _itoa(f4,temp,10);//将整数IP转化为一个字符串
IP="123.9.212.55";
m_cBtnStop.EnableWindow();
m_cBtnScan.EnableWindow(FALSE);
//是否是单个端口扫描
if (m_bSinglePort) //如果单个扫描值不为0
{
CString port;
m_cSinglePort.GetWindowText(port);//获取单扫描文本控件内的数据
m_minPort = m_maxPort = nSinglePort = atoi(port);//将字符串转换为整数类型
}
else//多端口
{
CString port1,port2;
m_cPortFrom.GetWindowText(port1);//获取多个扫描文本控件内的数据
m_cPortTo.GetWindowText(port2);//获取多个扫描文本控件内的数据
m_minPort = atoi(port1);//将字符串转换为整数类型
m_maxPort = atoi(port2);//将字符串转换为整数类型
m_cProgress.SetRange32(0,m_maxPort-m_minPort+1);//进度栏的最小值与最大值
m_cProgress.SetStep(1);//设置进度栏步长
}if (!m_bSinglePort && m_maxPort < m_minPort)//错误判断
{
MessageBox(_T("最大端口要大于最小端口."),
_T("Caution"),
MB_OK | MB_ICONINFORMATION);
return;
}
UINT m_nMaxAttempts = GetDlgItemInt(IDC_EDIT_ATTEMPTS);//将扫描次数的内容转换为整形数据
for (m_nCounter = m_minPort; m_nCounter <= m_maxPort; m_nCounter++)//循环扫描端口
{
AfxBeginThread(&CPortScanView::thread,this);
MSG message;
//以下消息用于等待Post出去的消息被响应,或者在限定时间内任务是否成功执行
//以下消息可以在执行这个函数时不至于没办法响应用户的操作
if (::PeekMessage(&message,NULL,0,0,PM_REMOVE))//为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。PM_REMOVE:PeekMessage处理后,消息从队列里除掉。
{
::TranslateMessage(&message);//该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。
::DispatchMessage(&message);//该函数调度一个消息给窗口程序
}
m_cProgress.StepIt();//按照当前步长更新进度栏位置
}
//设定状态栏
m_parent->SetStatusBarText((CString)_T("完毕"));//状态栏上显示文字
m_cBtnScan.EnableWindow();
m_cBtnStop.EnableWindow(FALSE);UINT CPortScanView::thread(LPVOID param1)
{
//((CPortScanView*)param1)->critical_section.Lock();
CPortScanView *param= new CPortScanView; param=(CPortScanView*)param1;
// ((CPortScanView*)param1)->critical_section.Unlock();
BOOL bIsOpen = FALSE;
UINT nAttempt = 1;
TCHAR temp[10]="\0";
UINT nIndex = 0;//索引
while(nAttempt <= ((CPortScanView*)param)->m_nMaxAttempts && !bIsOpen)//扫描次数并且标记不为假
{
CString str = _T("连接端口# ");
#ifdef _UNICODE
str += _itow(m_nCounter,temp,10);
#else
str += itoa(((CPortScanView*)param)->m_nCounter,temp,10);//将整数端口转化为一个字符串
#endif
str += _T(", IP地址=");
str += ((CPortScanView*)param)->IP;
str += _T(", Attempt=");
#ifdef _UNICODE
str += _itow(nAttempt,temp,10);
#else
str += itoa(nAttempt,temp,10);//将整数次数转化为一个字符串
#endif
//设定状态栏
((CPortScanView*)param)->m_parent->SetStatusBarText(str);//在状态栏显示字符串
str.Empty();//str的值变了. 将NULL字节放入CString
CTheSocket* pSocket;//Socket的派生类
pSocket = new CTheSocket;
ASSERT(pSocket);//如果条件返回错误,则终止程序执行
//创建socket
if (!pSocket->Create())//产生一个Socket句柄
{
//如果创建失败,则删除,返回 false
delete pSocket;
pSocket = NULL;
bIsOpen = FALSE;
}
//AfxMessageBox(itoa(((CPortScanView*)param)->m_nCounter,temp,10)) ;
//连接被连接的主机地址和指定端口
while (!pSocket->Connect(((CPortScanView*)param)->IP, ((CPortScanView*)param)->m_nCounter))//与未连接的数据流或数据报套接字进行连接(IP,端口)
{
//如果失败返回false
delete pSocket;
pSocket = NULL;
break;
// return FALSE;
}
//关闭Socket 连接并释放所有关联的资源
//pSocket->Close();
delete pSocket;
//return TRUE;//((CPortScanView*)param)->critical_section.Lock();
if (bIsOpen)//如果连接成功
{
DATA* pNode = new DATA;//自定义结构
ASSERT(pNode);//如果条件返回错误,则终止程序执行
//IP.GetLength()将返回字符串所占字节的数目
//GetBuffer为一个CString对象重新获取CString中的字符buffer,返回的LPTSTR为非const的
strcpy(pNode->IPAddress,((CPortScanView*)param)->IP.GetBuffer(((CPortScanView*)param)->IP.GetLength()));//把IP拷贝到DATA结构体的IPAddress
strcpy(pNode->port,_itoa(((CPortScanView*)param)->m_nCounter,temp,10));//将端口转换为字符拷贝到DATA结构体的port
pNode->bStatus = 1;//打开状态 1 = open , 0 = close
pNode->nAttempts = nAttempt;//扫描次数
((CPortScanView*)param)->AddItem(nIndex,0,((CPortScanView*)param)->IP);//在表格内添加IP记录
((CPortScanView*)param)->AddItem(nIndex,1,itoa(((CPortScanView*)param)->m_nCounter,temp,10));//在表格内添加端口记录
if (bIsOpen)
{
((CPortScanView*)param)->AddItem(nIndex,2,_T("打开"));
((CPortScanView*)param)->AddItem(nIndex,4,_T("*"));
}
else
{
((CPortScanView*)param)->AddItem(nIndex,2,_T("关闭"));
((CPortScanView*)param)->AddItem(nIndex,4,_T(" "));
}
((CPortScanView*)param)->AddItem(nIndex++,3,_itoa(1,temp,10));///在表格内添加扫描次数 //((CPortScanView*)param)->m_pStatusList->AddTail(pNode);//将一个元素(或另一个数组中的所有元素)添加到列表的尾部(产生一个新的尾部) }
//试图连接次数
nAttempt++;//次数++
//如果还是无法扫描成功
if (!bIsOpen)//如果连接失败
{
DATA* pNode = new DATA;//自定义结构
ASSERT(pNode);//如果条件返回错误,则终止程序执行
//IP.GetLength()将返回字符串所占字节的数目
//GetBuffer为一个CString对象重新获取CString中的字符buffer,返回的LPTSTR为非const的
strcpy(pNode->IPAddress,((CPortScanView*)param)->IP.GetBuffer(((CPortScanView*)param)->IP.GetLength()));//把IP拷贝到DATA结构体的IPAddress
strcpy(pNode->port,_itoa(((CPortScanView*)param)->m_nCounter,temp,10));//将端口转换为字符拷贝到DATA结构体的port
pNode->bStatus = 0; //关闭状态 1 = open , 0 = close
pNode->nAttempts = nAttempt-1;//扫描次数--
((CPortScanView*)param)->AddItem(nIndex,0,((CPortScanView*)param)->IP);//在表格内添加IP记录
((CPortScanView*)param)->AddItem(nIndex,1,itoa(((CPortScanView*)param)->m_nCounter,temp,10));//在表格内添加端口记录
if (bIsOpen)
{
((CPortScanView*)param)->AddItem(nIndex,2,_T("打开"));
((CPortScanView*)param)->AddItem(nIndex,4,_T("*"));
}
else
{
((CPortScanView*)param)->AddItem(nIndex,2,_T("关闭"));
((CPortScanView*)param)->AddItem(nIndex,4,_T(" "));
}
((CPortScanView*)param)->AddItem(nIndex++,3,_itoa(1,temp,10));///在表格内添加扫描次数
//((CPortScanView*)param)->m_pStatusList->AddTail(pNode);//将一个元素(或另一个数组中的所有元素)添加到列表的尾部(产生一个新的尾部)
}
//((CPortScanView*)param)->critical_section.Unlock();
}
//POSITION pos = ((CPortScanView*)param)->m_pStatusList->GetHeadPosition();//建立初始位置,并返回结点指针
////循环插入扫描结果
//
//
// // DATA* pNode;// = (DATA*)((CPortScanView*)param)->m_pStatusList->GetNext(pos);//获取用于反复的下一个元素
// ((CPortScanView*)param)->AddItem(nIndex,0,((CPortScanView*)param)->IP);//在表格内添加IP记录
// ((CPortScanView*)param)->AddItem(nIndex,1,itoa(((CPortScanView*)param)->m_nCounter,temp,10));//在表格内添加端口记录
// if (bIsOpen)
// {
// ((CPortScanView*)param)->AddItem(nIndex,2,_T("打开"));
// ((CPortScanView*)param)->AddItem(nIndex,4,_T("*"));
// }
// else
// {
// ((CPortScanView*)param)->AddItem(nIndex,2,_T("关闭"));
// ((CPortScanView*)param)->AddItem(nIndex,4,_T(" "));
// }
// ((CPortScanView*)param)->AddItem(nIndex++,3,_itoa(1,temp,10));///在表格内添加扫描次数 return 0;
}
解决方案 »
- vc6的gridctrl在哪里能找到啊?
- 怎么在Windows程序中显示C++的string字符串?
- vs2005编写的程序在vista下试图以管理员身份运行的问题
- 开发电子海图导航界面时,如何将我自己画的舰船根据GPS位置动态显示在海图上?
- 请教,今天去腾讯面试遇到的难题
- 哪一种驱动程序是在98 2000 xp 2003下都可以使用的?
- 五星级难题:::怎样实现j2me虚拟机:::(欢迎顶)
- 与delphi控件类似的东西
- COM接口的定义 (奇怪的错误,请高手指点)
- gif的动画用什么软件做最简便
- 如何在ComboBox中的下拉列表中显示图片 在线等~~~~~
- 应用FindFristFile,提示不能将char[] 转换成LPCTSTR
1、对CPortScanView内的方法的调用都是线程不安全的,需要做同步
2、就算做了同步,这样的程序结构也是不合理的,因为如果CPortScanView方法做了同步,那线程还有何意义,因为互相都阻塞了,再说传递全局对象指针进入线程并做大规模调用,那是相当不推荐的做法。
3、线程内while循环内建议在必要的地方加上sleep至少1毫秒,以避免CPU 100%
4、要保证程序退出后,如线程执行在一半,也能正常退出,所以就要求你能保证线程退出时CPortScanView指针所指对象等主线程对象还没被析构。