这是我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
然后直接跳出程序,下面的创建套接字就不执行了,这是我从书上找的代码,和书上的一样
编译调试都没问题了,可是就是捕获不到数据报,也展示不出来,哪位大侠帮我看看是哪里出了问题?
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
然后直接跳出程序,下面的创建套接字就不执行了,这是我从书上找的代码,和书上的一样
编译调试都没问题了,可是就是捕获不到数据报,也展示不出来,哪位大侠帮我看看是哪里出了问题?
{
//函数参数是对话框的指针
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);
}
还有你的线程函数threadFunc中的参数最好不要传递对话框的指针,MFC是非线程安全的,换成HWND句柄比较好。
m_threadid已经是全局的了