基於VC完成的收集監聽功效法式實例。本站提示廣大學習愛好者:(基於VC完成的收集監聽功效法式實例)文章只能為提供參考,不一定能成為您想要的結果。以下是基於VC完成的收集監聽功效法式實例正文
本文所述VC++收集監聽器代碼,可以完成監聽收集銜接所應用的協定、源IP地址、目的IP地址等信息的功效,而且能把數據內容綁定到網格控件中顯示。詳細功效代碼部門以下所示:
//線程函數
UINT ThreadFun( LPVOID pParam )
{
CSniffAppDlg* pDlg = static_cast<CSniffAppDlg*>(pParam);
MSG msg;
char buffer[1000],sourceip[32] ,*tempbuf;
char *ptemp;
BYTE* pData = NULL; //現實數據報中的數據
UINT sourceport ;
CString str;
HEADIP* pHeadIP;
HEADICMP* pHeadICMP;
HEADUDP* pHeadUDP;
HEADTCP* pHeadTCP;
in_addr addr;
int ret;
while (TRUE)
{
pData = NULL;
if (PeekMessage(&msg,pDlg->m_hWnd,WM_CLOSE,WM_CLOSE,PM_NOREMOVE ))
{
closesocket(pDlg->m_Sock);
break;
}
memset(buffer,0,1000);
ret = recv(pDlg->m_Sock,buffer,1000,0);
if (ret == SOCKET_ERROR)
{
continue;
}
else //吸收到數據
{
tempbuf = buffer;
pHeadIP = (HEADIP*)tempbuf;
//獲得數據報總長度
WORD len = ntohs(pHeadIP->totallen);
//獲得源IP
pDlg->m_List.InsertItem(pDlg->m_List.GetItemCount(),"");
addr.S_un.S_addr = pHeadIP->sourceIP;
ptemp = inet_ntoa(addr);
pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,1,ptemp);
//獲得目標IP
addr.S_un.S_addr = pHeadIP->destIP;
ptemp = inet_ntoa(addr);
pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,2,ptemp);
//獲得協定稱號
ptemp = get_protoname(pHeadIP->proto);
strcpy(sourceip,ptemp);
pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,0,sourceip);
//獲得IP數據報總長度
WORD ipSumLen = ntohs(pHeadIP->totallen);
//IP數據報頭總長度
int ipHeadLen = 20;
//取得去除IP層數據的長度
WORD netlen = ipSumLen - ipHeadLen;
//依據分歧年夜協定取得分歧協定的數據
switch (pHeadIP->proto)
{
case IPPROTO_ICMP:
{
pHeadICMP = (HEADICMP*)(tempbuf+20);
pData = (BYTE*)(pHeadICMP)+4; //ICMP數據報頭共4個字節
//獲得數據的長度
netlen -= 4;
break;
}
case IPPROTO_UDP:
{
pHeadUDP = (HEADUDP*)(tempbuf+20);
pData = (BYTE*)pHeadUDP+8; //UDP數據報頭共8個字節
sourceport = ntohs(pHeadUDP->SourcePort);
str.Format("%d",sourceport);
//設置源端口
pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,3,str);
str.Empty();
netlen -= 8;
break;
}
case IPPROTO_TCP:
{
pHeadTCP = (HEADTCP*)(tempbuf+20);
sourceport = ntohs(pHeadTCP->SourcePort);
pData = (BYTE*)pHeadTCP+20; //TCP數據報頭共20個字節
str.Format("%d",sourceport);
//設置源端口
pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,3,str);
str.Empty();
netlen-= 20;
break;
}
}
//設置數據年夜小
str.Format("%d",netlen);
pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,4,str);
str.Empty();
//設置數據
if (pData != NULL)
{
str.Format(" %s",pData);
pDlg->m_List.SetItemText(pDlg->m_List.GetItemCount()-1,5,str);
}
str.Empty();
}
}
return 0;
}
void CSniffAppDlg::OnBeginlisten()
{
//創立套接字
m_Sock = socket(AF_INET,SOCK_RAW, IPPROTO_IP );
char name[128];
memset(name,0,128);
hostent* phostent;
phostent = gethostbyname(name);
DWORD ip;
ip = inet_addr(inet_ntoa(*(in_addr*)phostent->h_addr_list[0]));
int timeout = 4000; //超時4秒
//設置吸收數據的超不時間
setsockopt(m_Sock,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout,sizeof(timeout));
sockaddr_in skaddr;
skaddr.sin_family = AF_INET;
skaddr.sin_port = htons(700);
skaddr.sin_addr.S_un.S_addr = ip;
//綁定地址
if ( bind(m_Sock,(sockaddr*)&skaddr,sizeof(skaddr))==SOCKET_ERROR)
{
MessageBox("地址綁定毛病");
return;
}
DWORD inBuffer=1;
DWORD outBuffer[10];
DWORD reValue = 0;
if (WSAIoctl(m_Sock,SIO_RCVALL,&inBuffer,sizeof(inBuffer),&outBuffer,sizeof(outBuffer),&reValue,NULL,NULL)==SOCKET_ERROR)
{
MessageBox("設置緩沖區毛病.");
closesocket(m_Sock);
return;
}
else
m_pThread = AfxBeginThread(ThreadFun,(void*)this);
}
void CSniffAppDlg::OnCancel()
{
if (m_pThread)
{
//m_pThread->ExitInstance();
delete m_pThread;
}
closesocket( m_Sock) ;
CDialog::OnCancel();
}
該實例只是功效部門重要代碼,讀者可依據本身項目需求停止測試,加以改良與完美以後整合進本身項目中去。