这是我sniffer程序中"查看"的模块
void CMySnifferDlg::OnBnClickedLookup()
{
// TODO: 在此添加控件通知处理程序代码
char szErr[50],szHostName[MAX_PATH];
DWORD dwErr;
SOCKADDR_IN sa;
//得到本机名
gethostname(szHostName,sizeof(szHostName));
m_iphostsource=m_ipsource;
m_ipcheckedhost=ntohl(m_iphost);
//判断是否有监听线程在执行
if(m_threadID==0)
{
SetDlgItemText(ID_LOOKUP,"停止查看");
}
else
{
if(m_threadID)
{
//向线程发送结束消息
PostThreadMessage(m_threadID,WM_CLOSE,0,0);
SetDlgItemText(ID_LOOKUP,"开始查看");
m_start.EnableWindow(FALSE);
}
return;
}
DWORD dwBufferLen[10];
DWORD dwBufferInLen=1;
DWORD* dwBytesReturned=NULL;
//创建原始套接字
m_s=socket(AF_INET,SOCK_RAW,IPPROTO_IP);

if(m_s==INVALID_SOCKET)
{
dwErr=WSAGetLastError();
sprintf(szErr,"Error socket()=%ld",dwErr);
AfxMessageBox(szErr);
closesocket(m_s);
return;
}
//设置套接字的接收超时选项
int rcvtimeo =5000;
if(setsockopt(m_s,SOL_SOCKET,SO_RCVTIMEO,(const char *)&rcvtimeo,sizeof(rcvtimeo))==SOCKET_ERROR)
{
dwErr=WSAGetLastError();
sprintf(szErr,"Error socket()=%ld",dwErr);
AfxMessageBox(szErr);
closesocket(m_s);
return;
}
sa.sin_family=AF_INET;
sa.sin_port=htons(7000);
sa.sin_addr.S_un.S_addr=m_iphostsource;
//绑定
if(bind(m_s,(PSOCKADDR)&sa,sizeof(sa))==SOCKET_ERROR)
{
dwErr=WSAGetLastError();
sprintf(szErr,"Error socket()=%ld",dwErr);
AfxMessageBox(szErr);
closesocket(m_s);
return;
}
//设置socket模式
if(SOCKET_ERROR!=WSAIoctl(m_s,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),dwBytesReturned,NULL,NULL))
//开启一个监听线程
AfxBeginThread(threadFunc,(LPVOID)this);
else
{
dwErr=WSAGetLastError();
sprintf(szErr,"Error socket()=%ld",dwErr);
AfxMessageBox(szErr);
closesocket(m_s);
return;
}
}
当我单步调试的时候发现程序运行到
if(m_threadID)
{
//向线程发送结束消息
PostThreadMessage(m_threadID,WM_CLOSE,0,0);
SetDlgItemText(ID_LOOKUP,"开始查看");
m_start.EnableWindow(FALSE);
}
return;
m_threadID=3435973836
然后直接跳出程序,下面的创建套接字就不执行了,这是我从书上找的代码,和书上的一样
编译调试都没问题了,可是就是捕获不到数据报,也展示不出来,哪位大侠帮我看看是哪里出了问题?

解决方案 »

  1.   

    还有就是为什么当m_threadID=3435973836不为0时要终止线程啊!!
      

  2.   

    UINT threadFunc(LPVOID p)
    {
    //函数参数是对话框的指针
    CMySnifferDlg *pDlg=static_cast<CMySnifferDlg *>(p);
    char buf[1000],*bufwork;
    MSG msg;
    int iRet;
    DWORD dwErr;
    char *pSource,*pDest;
    IPHEADER *pIpHeader;
    in_addr ina;
    char szSource[16],szDest[16],szErr[50];
    char *pLastBuf=NULL;
    int HdrLen,totallen;
    WORD sourport,destport;
    //定义头结构变量
    struct TCPPacketHead *pTCPHead;
    struct ICMPPacketHead *pICMPHead;
    struct UDPPacketHead *pUDPHead;
    BYTE *pdata=NULL;
    PeekMessage(&msg,NULL,WM_USER,WM_USER,PM_NOREMOVE);
    //获取线程ID
    pDlg->m_threadID=GetCurrentThreadId();
    while(TRUE)
    {
    //检测消息队列中的WM_CLOSE消息
    if(PeekMessage(&msg,0,WM_CLOSE,WM_CLOSE,PM_NOREMOVE))
    {
    closesocket(pDlg->m_s);
    pDlg->m_threadID=0;
    pDlg->m_start.EnableWindow(TRUE);
    break;
    }
    memset(buf,0,sizeof(buf));
    //接收数据
    iRet=recv(pDlg->m_s,buf,sizeof(buf),0);
    if(iRet==SOCKET_ERROR)
    {
    dwErr=WSAGetLastError();
    sprintf(szErr,"Error socket()=%ld",dwErr);
    continue;
    }
    else
    if(*buf)
    {
    bufwork=buf;
    //获取IP包的头
    pIpHeader=(IPHEADER *)bufwork;
    WORD iLen=ntohs(pIpHeader->total_len);
    while(TRUE)
    {
    if(iLen<=iRet)
    {
    ina.S_un.S_addr=pIpHeader->sourceIP;
    //获取源地址
    pSource=inet_ntoa(ina);
    strcpy(szSource,pSource);
    ina.S_un.S_addr=pIpHeader->destIP;
    pDest=inet_ntoa(ina);
    strcpy(szDest,pDest);
    CString str,strProto,strSourPort,strDestPort,strData,strSize;
    //得到数据报协议名称
    strProto=get_proto_name(pIpHeader->proto);
    HdrLen=pIpHeader->header_len&0xf;
    HdrLen*=4;
    totallen=ntohs(pIpHeader->total_len);
    totallen-=HdrLen;
    //对不同协议的头部数据进行分析
    switch(pIpHeader->proto)
    {
    case IPPROTO_ICMP:
    {
    pICMPHead=(struct ICMPPacketHead *)(buf+HdrLen);
    strSourPort="-";
    strDestPort="-";
    pdata=((BYTE *)pICMPHead)+ICMP_HEAD_LEN;
    totallen-=ICMP_HEAD_LEN;
    break;
    }
    case IPPROTO_TCP:
    {
    pTCPHead=(struct TCPPacketHead *)(buf+HdrLen);
    //得到源端口和目的端口
    sourport=ntohs(pTCPHead->SourPort);
    destport=ntohs(pTCPHead->DestPort);
    strSourPort.Format("%d",sourport);
    strDestPort.Format("%d",destport);
    HdrLen=(pTCPHead->HLen)>>4;
    HdrLen*=4;
    pdata=((BYTE *)pTCPHead)+HdrLen;
    totallen-=HdrLen;
    break;
    }
    case IPPROTO_UDP:
    {
    pUDPHead=(struct UDPPacketHead *)(buf+HdrLen);
    //得到源端口和目的端口
    sourport=ntohs(pUDPHead->SourPort);
    destport=ntohs(pUDPHead->DestPort);
    strSourPort.Format("%d",sourport);
    strDestPort.Format("%d",destport);
    pdata=((BYTE *)pUDPHead)+UDP_HEAD_LEN;
    totallen-=UDP_HEAD_LEN;
    break;
    }
    }
    //ICMP协议数据分析
    if(pIpHeader->proto==IPPROTO_ICMP)
    strData.Format("type:%d code:%d data:%s",pICMPHead->Type,pICMPHead->Code,pdata);
    else
    strData.Format("  %s",pdata);
    strSize.Format("%d",totallen);
    //将上面的结构添加到ListControl
    pDlg->AddData(strProto,szSource,strSourPort,szDest,strDestPort,strSize,strData);
    if(iLen<iRet)
    {
    iRet-=iLen;
    bufwork+=iLen;
    pIpHeader=(IPHEADER *)bufwork;
    }
    else
    break;   //如果pIpHeader->total_len==iRet则退出
    }
    else//已经读到buffer的最后部分,即包的长度
    {
    int iLast=iLen-iRet;
    pLastBuf=new char [iLen];
    int iReaden=iRet;
    memcpy(pLastBuf,bufwork,iReaden);
    iRet=recv(pDlg->m_s,pLastBuf+iReaden,iLast,0);
    if(iRet==SOCKET_ERROR)
    {
    dwErr=WSAGetLastError();
    sprintf(szErr,"Error socket()=%ld",dwErr);
    break;
    }
    else
    {
    bufwork=pLastBuf;
    pIpHeader=(IPHEADER *)bufwork;
    if(iRet==iLast)
    iRet=iLen;
    else
    {
    //读剩下的所有数据
    iReaden+=iRet;
    iLast-=iRet;
    while(TRUE)
    {
    iRet=recv(pDlg->m_s,pLastBuf+iReaden,iLast,0);
    if(iRet==SOCKET_ERROR)
    {
    dwErr=WSAGetLastError();
    sprintf(szErr,"Error socket()=%ld",dwErr);
    break;
    }
    else
    {
    iReaden+=iRet;
    iLast-=iRet;
    if(iLast<=0)
    break; }
    }
    }
    }
    }
    }
    if(pLastBuf)
    delete [] pLastBuf;
    }
    else
    {
    AfxMessageBox("网络中没有数据!");
    continue;
    }
    }
    return TRUE;
    }void CMySnifferDlg::AddData(CString s0,CString s1,CString s2,CString s3,CString s4,CString s5,CString s6)
    {
    int index;
    index=m_ctrList.InsertItem(0,s0);
    m_ctrList.SetItem(index,1,LVIF_TEXT,s1,0,0,0,0);
    m_ctrList.SetItem(index,2,LVIF_TEXT,s2,0,0,0,0);
    m_ctrList.SetItem(index,3,LVIF_TEXT,s3,0,0,0,0);
    m_ctrList.SetItem(index,4,LVIF_TEXT,s4,0,0,0,0);
    m_ctrList.SetItem(index,5,LVIF_TEXT,s5,0,0,0,0);
    m_ctrList.SetItem(index,6,LVIF_TEXT,s6,0,0,0,0);
    }
      

  3.   

    是看你创建线程的语句,AfxBeginThread,不是看你线程函数。
    还有你的线程函数threadFunc中的参数最好不要传递对话框的指针,MFC是非线程安全的,换成HWND句柄比较好。
      

  4.   

    m_threadID你写成全局的或者静态的看看还有这个问题吗????
      

  5.   

    AfxBeginThread书上就这个开启线程函数,没有创建线程的,
    m_threadid已经是全局的了